diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.bower.json b/views/ngXosViews/serviceGrid/src/vendor/lodash/.bower.json
new file mode 100644
index 0000000..6b70939
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.bower.json
@@ -0,0 +1,14 @@
+{
+  "name": "lodash",
+  "homepage": "https://github.com/lodash/lodash",
+  "version": "4.11.2",
+  "_release": "4.11.2",
+  "_resolution": {
+    "type": "version",
+    "tag": "4.11.2",
+    "commit": "64fbb18fc7a4dd44240e25ed9cac2576b16f45a3"
+  },
+  "_source": "https://github.com/lodash/lodash.git",
+  "_target": "~4.11.1",
+  "_originalSource": "lodash"
+}
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.editorconfig b/views/ngXosViews/serviceGrid/src/vendor/lodash/.editorconfig
new file mode 100644
index 0000000..b889a36
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.editorconfig
@@ -0,0 +1,12 @@
+# This file is for unifying the coding style for different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.gitattributes b/views/ngXosViews/serviceGrid/src/vendor/lodash/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.github/CONTRIBUTING.md b/views/ngXosViews/serviceGrid/src/vendor/lodash/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..b3427fd
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.github/CONTRIBUTING.md
@@ -0,0 +1,78 @@
+# Contributing to Lodash
+
+Contributions are always welcome. Before contributing please read the
+[code of conduct](https://github.com/lodash/lodash/blob/master/CODE_OF_CONDUCT.md)
+& [search the issue tracker](https://github.com/lodash/lodash/issues); your issue
+may have already been discussed or fixed in `master`. To contribute,
+[fork](https://help.github.com/articles/fork-a-repo/) Lodash, commit your changes,
+& [send a pull request](https://help.github.com/articles/using-pull-requests/).
+
+## Feature Requests
+
+Feature requests should be submitted in the
+[issue tracker](https://github.com/lodash/lodash/issues), with a description of
+the expected behavior & use case, where they’ll remain closed until sufficient interest,
+[e.g. :+1: reactions](https://help.github.com/articles/about-discussions-in-issues-and-pull-requests/),
+has been shown by the community. Before submitting a request, please search for
+similar ones in the
+[closed issues](https://github.com/lodash/lodash/issues?q=is%3Aissue+is%3Aclosed+label%3Aenhancement).
+
+## Pull Requests
+
+For additions or bug fixes you should only need to modify `lodash.js`. Include
+updated unit tests in the `test` directory as part of your pull request. Don’t
+worry about regenerating the `dist/` or `doc/` files.
+
+Before running the unit tests you’ll need to install, `npm i`,
+[development dependencies](https://docs.npmjs.com/files/package.json#devdependencies).
+Run unit tests from the command-line via `npm test`, or open `test/index.html` &
+`test/fp.html` in a web browser. The [Backbone](http://backbonejs.org/) &
+[Underscore](http://underscorejs.org/) test suites are included as well.
+
+## Contributor License Agreement
+
+Lodash is a member of the [jQuery Foundation](https://jquery.org/).
+As such, we request that all contributors sign the jQuery Foundation
+[contributor license agreement (CLA)](https://contribute.jquery.org/CLA/).
+
+For more information about CLAs, please check out Alex Russell’s excellent post,
+[“Why Do I Need to Sign This?”](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
+
+## Coding Guidelines
+
+In addition to the following guidelines, please follow the conventions already
+established in the code.
+
+- **Spacing**:<br>
+  Use two spaces for indentation. No tabs.
+
+- **Naming**:<br>
+  Keep variable & method names concise & descriptive.<br>
+  Variable names `index`, `collection`, & `callback` are preferable to
+  `i`, `arr`, & `fn`.
+
+- **Quotes**:<br>
+  Single-quoted strings are preferred to double-quoted strings; however,
+  please use a double-quoted string if the value contains a single-quote
+  character to avoid unnecessary escaping.
+
+- **Comments**:<br>
+  Please use single-line comments to annotate significant additions, &
+  [JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for
+  functions.
+
+Guidelines are enforced using [JSCS](https://www.npmjs.com/package/jscs):
+```bash
+$ npm run style
+```
+
+## Tips
+
+You can opt-in to a pre-push git hook by adding an `.opt-in` file to the root of
+the project containing:
+```txt
+pre-push
+```
+
+With that, when you `git push`, the pre-push git hook will trigger and execute
+`npm run validate`.
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.gitignore b/views/ngXosViews/serviceGrid/src/vendor/lodash/.gitignore
new file mode 100644
index 0000000..6eb2db8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.gitignore
@@ -0,0 +1,9 @@
+.DS_Store
+*.custom.*
+*.log
+*.map
+lodash.compat.min.js
+coverage
+node_modules
+.opt-in
+.opt-out
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.jscsrc b/views/ngXosViews/serviceGrid/src/vendor/lodash/.jscsrc
new file mode 100644
index 0000000..5f44ab8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.jscsrc
@@ -0,0 +1,97 @@
+{
+    "maxErrors": "2000",
+    "maximumLineLength": {
+      "value": 180,
+      "allExcept": ["comments", "functionSignature", "regex"]
+    },
+    "requireCurlyBraces": [
+        "if",
+        "else",
+        "for",
+        "while",
+        "do",
+        "try",
+        "catch"
+    ],
+    "requireOperatorBeforeLineBreak": [
+        "=",
+        "+",
+        "-",
+        "/",
+        "*",
+        "==",
+        "===",
+        "!=",
+        "!==",
+        ">",
+        ">=",
+        "<",
+        "<="
+    ],
+    "requireSpaceAfterKeywords": [
+      "if",
+      "else",
+      "for",
+      "while",
+      "do",
+      "switch",
+      "return",
+      "try",
+      "catch"
+    ],
+    "requireSpaceBeforeBinaryOperators": [
+        "=", "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=",
+        "&=", "|=", "^=", "+=",
+
+        "+", "-", "*", "/", "%", "<<", ">>", ">>>", "&",
+        "|", "^", "&&", "||", "===", "==", ">=",
+        "<=", "<", ">", "!=", "!=="
+    ],
+    "requireSpacesInFunctionExpression": {
+        "beforeOpeningCurlyBrace": true
+    },
+    "requireCamelCaseOrUpperCaseIdentifiers": true,
+    "requireDotNotation": { "allExcept": ["keywords"] },
+    "requireEarlyReturn": true,
+    "requireLineFeedAtFileEnd": true,
+    "requireSemicolons": true,
+    "requireSpaceAfterBinaryOperators": true,
+    "requireSpacesInConditionalExpression": true,
+    "requireSpaceBeforeObjectValues": true,
+    "requireSpaceBeforeBlockStatements": true,
+    "requireSpacesInForStatement": true,
+
+    "validateIndentation": 2,
+    "validateParameterSeparator": ", ",
+    "validateQuoteMarks": { "mark": "'", "escape": true },
+
+    "disallowSpacesInAnonymousFunctionExpression": {
+        "beforeOpeningRoundBrace": true
+    },
+    "disallowSpacesInFunctionDeclaration": {
+        "beforeOpeningRoundBrace": true
+    },
+    "disallowSpacesInFunctionExpression": {
+        "beforeOpeningRoundBrace": true
+    },
+    "disallowKeywords": ["with"],
+    "disallowMixedSpacesAndTabs": true,
+    "disallowMultipleLineBreaks": true,
+    "disallowNewlineBeforeBlockStatements": true,
+    "disallowSpaceAfterObjectKeys": true,
+    "disallowSpaceAfterPrefixUnaryOperators": true,
+    "disallowSpacesInCallExpression": true,
+    "disallowSpacesInsideArrayBrackets": true,
+    "disallowSpacesInsideParentheses": true,
+    "disallowTrailingWhitespace": true,
+    "disallowUnusedVariables": true,
+
+    "jsDoc": {
+        "checkRedundantAccess": true,
+        "checkTypes": true,
+        "requireNewlineAfterDescription": true,
+        "requireParamDescription": true,
+        "requireParamTypes": true,
+        "requireReturnTypes": true
+    }
+}
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/.travis.yml b/views/ngXosViews/serviceGrid/src/vendor/lodash/.travis.yml
new file mode 100644
index 0000000..161f0cd
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/.travis.yml
@@ -0,0 +1,77 @@
+language: node_js
+sudo: false
+node_js:
+  - "5"
+env:
+  global:
+    - BIN="node" ISTANBUL=false OPTION=""
+    - SAUCE_LABS=false SAUCE_USERNAME="lodash"
+    - secure: "tg1JFsIFnxzLaTboFPOnm+aJCuMm5+JdhLlESlqg9x3fwro++7KCnwHKLNovhchaPe4otC43ZMB/nfWhDnDm11dKbm/V6HlTkED+dadTsaLxVDg6J+7yK41QhokBPJOxLV78iDaNaAQVYEirAgZ0yn8kFubxmNKV+bpCGQNc9yU="
+  matrix:
+    -
+    - BIN="phantomjs"
+    - ISTANBUL=true
+    - SAUCE_LABS=true
+matrix:
+  include:
+    - node_js: "0.10"
+      env:
+    - node_js: "0.12"
+      env:
+    - node_js: "4"
+      env:
+git:
+  depth: 10
+branches:
+  only:
+    - master
+notifications:
+  webhooks:
+    urls:
+      - https://webhooks.gitter.im/e/4aab6358b0e9aed0b628
+    on_success: change
+    on_failure: always
+before_install:
+  - "nvm use $TRAVIS_NODE_VERSION"
+  - "npm set loglevel error"
+  - "npm set progress false"
+  - "npm i -g npm@\"^2.0.0\""
+  - |
+      PATTERN[0]="|\s*if\s*\(isHostObject\b[\s\S]+?\}(?=\n)|"
+      PATTERN[1]="|\s*if\s*\(enumerate\b[\s\S]+?\};\s*\}|"
+      PATTERN[2]="|\s*while\s*\([^)]+\)\s*\{\s*iteratee\(index\);\s*\}|"
+      PATTERN[3]="|\s*else\s*\{\s*assocSet\(data\b[\s\S]+?\}|"
+      PATTERN[4]="|\bcase\s+(?:dataView|set|map|weakMap)CtorString:.+|g"
+      PATTERN[5]="|\bindex,\s*iterable\)\s*===\s*false\)[^}]+?(break;)|"
+      PATTERN[6]="|\s*if\s*\(\!lodashFunc\)\s*\{\s*return;\s*\}|"
+      PATTERN[7]="|\s*define\([\s\S]+?\);|"
+      PATTERN[8]="|\s*root\._\s*=\s*_;|"
+
+      if [ $ISTANBUL == true ]; then
+        set -e
+        for PTRN in ${PATTERN[@]}; do
+          node ./test/remove.js "$PTRN" ./lodash.js
+        done
+      fi
+  - "git clone --depth=10 --branch=master git://github.com/lodash/lodash-cli ./node_modules/lodash-cli && mkdir $_/node_modules && cd $_ && ln -s ../../../ ./lodash && cd ../ && npm i && cd ../../"
+  - "node ./node_modules/lodash-cli/bin/lodash -o ./dist/lodash.js"
+script:
+  - "[ $ISTANBUL == false ]   || istanbul cover -x \"**/vendor/**\" --report lcovonly ./test/test.js -- ./lodash.js"
+  - "[ $ISTANBUL == false ]   || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/lcov.info | coveralls) || true"
+  - "[ $ISTANBUL == false ]   || [ $TRAVIS_SECURE_ENV_VARS == false ] || (cat ./coverage/coverage.json | codecov) || true"
+  - "[ $SAUCE_LABS == true ]  || [ $ISTANBUL == true ] || cd ./test"
+  - "[ $SAUCE_LABS == true ]  || [ $ISTANBUL == true ] || $BIN $OPTION ./test.js ../lodash.js"
+  - "[ $SAUCE_LABS == true ]  || [ $ISTANBUL == true ] || [ $TRAVIS_SECURE_ENV_VARS == false ] || $BIN $OPTION ./test.js ../dist/lodash.min.js"
+  - "[ $SAUCE_LABS == false ] || rm -rf ./node_modules/lodash"
+  - "[ $SAUCE_LABS == false ] || ($BIN ./node_modules/lodash-cli/bin/lodash -d -o ./node_modules/lodash/index.js && cd ./node_modules/lodash/ && ln -s ./index.js ./lodash.js && cd ../../)"
+  - "[ $SAUCE_LABS == false ] || $BIN ./node_modules/lodash-cli/bin/lodash core -o ./dist/lodash.core.js"
+  - "[ $SAUCE_LABS == false ] || npm run build"
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\"     runner=\"test/index.html?build=../dist/lodash.js&noglobals=true\"     tags=\"development\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash tests\"     runner=\"test/index.html?build=../dist/lodash.min.js&noglobals=true\" tags=\"production\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"lodash-fp tests\"  runner=\"test/fp.html?noglobals=true\"                                tags=\"development\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../dist/lodash.js\"               tags=\"development,underscore\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"underscore tests\" runner=\"test/underscore.html?build=../dist/lodash.min.js\"           tags=\"production,underscore\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\"   runner=\"test/backbone.html?build=../dist/lodash.js\"                 tags=\"development,backbone\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\"   runner=\"test/backbone.html?build=../dist/lodash.min.js\"             tags=\"production,backbone\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\"   runner=\"test/backbone.html?build=../dist/lodash.core.js\"            tags=\"development,backbone\""
+  - "[ $SAUCE_LABS == false ] || $BIN ./test/saucelabs.js name=\"backbone tests\"   runner=\"test/backbone.html?build=../dist/lodash.core.min.js\"        tags=\"production,backbone\""
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/LICENSE b/views/ngXosViews/serviceGrid/src/vendor/lodash/LICENSE
new file mode 100644
index 0000000..e0c69d5
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/LICENSE
@@ -0,0 +1,47 @@
+Copyright jQuery Foundation and other contributors <https://jquery.org/>
+
+Based on Underscore.js, copyright Jeremy Ashkenas,
+DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
+
+This software consists of voluntary contributions made by many
+individuals. For exact contribution history, see the revision history
+available at https://github.com/lodash/lodash
+
+The following license applies to all parts of this software except as
+documented below:
+
+====
+
+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.
+
+====
+
+Copyright and related rights for sample code are waived via CC0. Sample
+code is defined as all source code displayed within the prose of the
+documentation.
+
+CC0: http://creativecommons.org/publicdomain/zero/1.0/
+
+====
+
+Files located in the node_modules and vendor directories are externally
+maintained libraries used by this software which have their own
+licenses; we recommend you read them, as their terms may differ from the
+terms above.
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/README.md b/views/ngXosViews/serviceGrid/src/vendor/lodash/README.md
new file mode 100644
index 0000000..fe14559
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/README.md
@@ -0,0 +1,46 @@
+# lodash v4.11.2
+
+[Site](https://lodash.com/) |
+[Docs](https://lodash.com/docs) |
+[FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) |
+[Contributing](https://github.com/lodash/lodash/blob/4.11.2/.github/CONTRIBUTING.md) |
+[Wiki](https://github.com/lodash/lodash/wiki "Changelog, Roadmap, etc.") |
+[Code of Conduct](https://jquery.org/conduct/) |
+[Twitter](https://twitter.com/bestiejs) |
+[Chat](https://gitter.im/lodash/lodash)
+
+The [Lodash](https://lodash.com/) library exported as a [UMD](https://github.com/umdjs/umd) module.
+
+Generated using [lodash-cli](https://www.npmjs.com/package/lodash-cli):
+```bash
+$ npm run build
+$ lodash -o ./dist/lodash.js
+$ lodash core -o ./dist/lodash.core.js
+```
+
+## Download
+
+Lodash is released under the [MIT license](https://raw.githubusercontent.com/lodash/lodash/4.11.2/LICENSE) & supports [modern environments](#support).<br>
+Review the [build differences](https://github.com/lodash/lodash/wiki/build-differences) & pick one that’s right for you.
+
+ * [Core build](https://raw.githubusercontent.com/lodash/lodash/4.11.2/dist/lodash.core.js) ([~4 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.11.2/dist/lodash.core.min.js))
+ * [Full build](https://raw.githubusercontent.com/lodash/lodash/4.11.2/dist/lodash.js) ([~22 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.11.2/dist/lodash.min.js))
+ * [CDN copies](https://www.jsdelivr.com/projects/lodash)
+
+## Why Lodash?
+
+Lodash makes JavaScript easier by taking the hassle out of working with arrays,<br>
+numbers, objects, strings, etc. Lodash’s modular methods are great for:
+
+* Iterating arrays, objects, & strings
+* Manipulating & testing values
+* Creating composite functions
+
+## Module Formats
+
+Lodash is available in a [variety of builds](https://lodash.com/custom-builds) & module formats.
+
+ * [lodash](https://www.npmjs.com/package/lodash) & [per method packages](https://www.npmjs.com/browse/keyword/lodash-modularized)
+ * [lodash-amd](https://www.npmjs.com/package/lodash-amd)
+ * [lodash-es](https://www.npmjs.com/package/lodash-es) & [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash)
+ * [lodash/fp](https://github.com/lodash/lodash/tree/4.11.2-npm/fp)
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.core.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.core.js
new file mode 100644
index 0000000..73b541b
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.core.js
@@ -0,0 +1,3978 @@
+/**
+ * @license
+ * lodash 4.11.2 (Custom Build) <https://lodash.com/>
+ * Build: `lodash core -o ./dist/lodash.core.js`
+ * Copyright jQuery Foundation and other contributors <https://jquery.org/>
+ * 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.11.2';
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT = 'Expected a function';
+
+  /** Used to compose bitmasks for wrapper metadata. */
+  var BIND_FLAG = 1,
+      PARTIAL_FLAG = 32;
+
+  /** Used to compose bitmasks for comparison styles. */
+  var UNORDERED_COMPARE_FLAG = 1,
+      PARTIAL_COMPARE_FLAG = 2;
+
+  /** Used as references for various `Number` constants. */
+  var INFINITY = 1 / 0,
+      MAX_SAFE_INTEGER = 9007199254740991;
+
+  /** `Object#toString` result references. */
+  var argsTag = '[object Arguments]',
+      arrayTag = '[object Array]',
+      boolTag = '[object Boolean]',
+      dateTag = '[object Date]',
+      errorTag = '[object Error]',
+      funcTag = '[object Function]',
+      genTag = '[object GeneratorFunction]',
+      numberTag = '[object Number]',
+      objectTag = '[object Object]',
+      regexpTag = '[object RegExp]',
+      stringTag = '[object String]';
+
+  /** Used to match HTML entities and HTML characters. */
+  var reUnescapedHtml = /[&<>"'`]/g,
+      reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+  /** Used to detect unsigned integer values. */
+  var reIsUint = /^(?:0|[1-9]\d*)$/;
+
+  /** Used to map characters to HTML entities. */
+  var htmlEscapes = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;',
+    '`': '&#96;'
+  };
+
+  /** Used to determine if values are of the language type `Object`. */
+  var objectTypes = {
+    'function': true,
+    'object': true
+  };
+
+  /** Detect free variable `exports`. */
+  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+    ? exports
+    : undefined;
+
+  /** Detect free variable `module`. */
+  var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+    ? module
+    : undefined;
+
+  /** Detect the popular CommonJS extension `module.exports`. */
+  var moduleExports = (freeModule && freeModule.exports === freeExports)
+    ? freeExports
+    : undefined;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+  /** Detect free variable `self`. */
+  var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+  /** Detect free variable `window`. */
+  var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+  /** Detect `this` as the global object. */
+  var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+  /**
+   * Used as a reference to the global object.
+   *
+   * The `this` value is used if it's the global object to avoid Greasemonkey's
+   * restricted `window` object, otherwise the `window` object is used.
+   */
+  var root = freeGlobal ||
+    ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+      freeSelf || thisGlobal || Function('return this')();
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Creates a new array concatenating `array` with `other`.
+   *
+   * @private
+   * @param {Array} array The first array to concatenate.
+   * @param {Array} other The second array to concatenate.
+   * @returns {Array} Returns the new concatenated array.
+   */
+  function arrayConcat(array, other) {
+    return arrayPush(copyArray(array), values);
+  }
+
+  /**
+   * 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) {
+    array.push.apply(array, values);
+    return array;
+  }
+
+  /**
+   * The base implementation of methods like `_.find` and `_.findKey`, without
+   * support for iteratee shorthands, which iterates over `collection` using
+   * `eachFunc`.
+   *
+   * @private
+   * @param {Array|Object} collection The collection to search.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {Function} eachFunc The function to iterate over `collection`.
+   * @param {boolean} [retKey] Specify returning the key of the found element
+   *  instead of the element itself.
+   * @returns {*} Returns the found element or its key, else `undefined`.
+   */
+  function baseFind(collection, predicate, eachFunc, retKey) {
+    var result;
+    eachFunc(collection, function(value, key, collection) {
+      if (predicate(value, key, collection)) {
+        result = retKey ? key : value;
+        return false;
+      }
+    });
+    return result;
+  }
+
+  /**
+   * 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 `_.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 `_.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 baseMap(props, function(key) {
+      return object[key];
+    });
+  }
+
+  /**
+   * Checks if `value` is a global object.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+   */
+  function checkGlobal(value) {
+    return (value && value.Object === Object) ? value : null;
+  }
+
+  /**
+   * Used by `_.escape` to convert characters to HTML entities.
+   *
+   * @private
+   * @param {string} chr The matched character to escape.
+   * @returns {string} Returns the escaped character.
+   */
+  function escapeHtmlChar(chr) {
+    return htmlEscapes[chr];
+  }
+
+  /**
+   * Checks if `value` is a host object in IE < 9.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+   */
+  function isHostObject(value) {
+    // Many host objects are `Object` objects that can coerce to strings
+    // despite having improperly defined `toString` methods.
+    var result = false;
+    if (value != null && typeof value.toString != 'function') {
+      try {
+        result = !!(value + '');
+      } catch (e) {}
+    }
+    return result;
+  }
+
+  /**
+   * 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;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /** Used for built-in method references. */
+  var arrayProto = Array.prototype,
+      objectProto = Object.prototype;
+
+  /** Used to check objects for own properties. */
+  var hasOwnProperty = objectProto.hasOwnProperty;
+
+  /** Used to generate unique IDs. */
+  var idCounter = 0;
+
+  /**
+   * Used to resolve the
+   * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+   * of values.
+   */
+  var objectToString = objectProto.toString;
+
+  /** Used to restore the original `_` reference in `_.noConflict`. */
+  var oldDash = root._;
+
+  /** Built-in value references. */
+  var Reflect = root.Reflect,
+      Symbol = root.Symbol,
+      Uint8Array = root.Uint8Array,
+      enumerate = Reflect ? Reflect.enumerate : undefined,
+      objectCreate = Object.create,
+      propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+  /* Built-in method references for those with the same name as other `lodash` methods. */
+  var nativeIsFinite = root.isFinite,
+      nativeKeys = Object.keys,
+      nativeMax = Math.max;
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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 of at least `200` elements
+   * and any 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`, `deburr`, `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`, `subtract`, `sum`, `sumBy`, `template`, `times`, `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) {
+    return value instanceof LodashWrapper
+      ? value
+      : new LodashWrapper(value);
+  }
+
+  /**
+   * 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;
+  }
+
+  LodashWrapper.prototype = baseCreate(lodash.prototype);
+  LodashWrapper.prototype.constructor = LodashWrapper;
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * Used by `_.defaults` to customize its `_.assignIn` use.
+   *
+   * @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 assignInDefaults(objValue, srcValue, key, object) {
+    if (objValue === undefined ||
+        (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+      return srcValue;
+    }
+    return objValue;
+  }
+
+  /**
+   * Assigns `value` to `key` of `object` if the existing value is not equivalent
+   * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.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))) {
+      object[key] = value;
+    }
+  }
+
+  /**
+   * The base implementation of `_.create` without support for assigning
+   * properties to the created object.
+   *
+   * @private
+   * @param {Object} prototype The object to inherit from.
+   * @returns {Object} Returns the new object.
+   */
+  function baseCreate(proto) {
+    return isObject(proto) ? objectCreate(proto) : {};
+  }
+
+  /**
+   * The base implementation of `_.delay` and `_.defer` which accepts an array
+   * of `func` arguments.
+   *
+   * @private
+   * @param {Function} func The function to delay.
+   * @param {number} wait The number of milliseconds to delay invocation.
+   * @param {Object} args The arguments to provide to `func`.
+   * @returns {number} Returns the timer id.
+   */
+  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 `_.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 `_.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 && !false)
+            : comparator(current, computed)
+          )) {
+        var computed = current,
+            result = value;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * 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();
+
+  /**
+   * 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 `_.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 new array of filtered property names.
+   */
+  function baseFunctions(object, props) {
+    return baseFilter(props, function(key) {
+      return isFunction(object[key]);
+    });
+  }
+
+  /**
+   * The base implementation of `_.gt` which doesn't coerce arguments to numbers.
+   *
+   * @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 `_.isEqual` which supports partial comparisons
+   * and tracks traversed objects.
+   *
+   * @private
+   * @param {*} value The value to compare.
+   * @param {*} other The other value to compare.
+   * @param {Function} [customizer] The function to customize comparisons.
+   * @param {boolean} [bitmask] The bitmask of comparison flags.
+   *  The bitmask may be composed of the following flags:
+   *     1 - Unordered comparison
+   *     2 - Partial comparison
+   * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+   */
+  function baseIsEqual(value, other, customizer, bitmask, stack) {
+    if (value === other) {
+      return true;
+    }
+    if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+      return value !== value && other !== other;
+    }
+    return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, 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 {Function} equalFunc The function to determine equivalents of values.
+   * @param {Function} [customizer] The function to customize comparisons.
+   * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
+   *  for more details.
+   * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+   */
+  function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
+    var objIsArr = isArray(object),
+        othIsArr = isArray(other),
+        objTag = arrayTag,
+        othTag = arrayTag;
+
+    if (!objIsArr) {
+      objTag = objectToString.call(object);
+      objTag = objTag == argsTag ? objectTag : objTag;
+    }
+    if (!othIsArr) {
+      othTag = objectToString.call(other);
+      othTag = othTag == argsTag ? objectTag : othTag;
+    }
+    var objIsObj = objTag == objectTag && !isHostObject(object),
+        othIsObj = othTag == objectTag && !isHostObject(other),
+        isSameTag = objTag == othTag;
+
+    stack || (stack = []);
+    var stacked = find(stack, function(entry) {
+      return entry[0] === object;
+    });
+    if (stacked && stacked[1]) {
+      return stacked[1] == other;
+    }
+    stack.push([object, other]);
+    if (isSameTag && !objIsObj) {
+      var result = (objIsArr || isTypedArray(object))
+        ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
+        : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
+      stack.pop();
+      return result;
+    }
+    if (!(bitmask & PARTIAL_COMPARE_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;
+
+        var result = equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack);
+        stack.pop();
+        return result;
+      }
+    }
+    if (!isSameTag) {
+      return false;
+    }
+    var result = equalObjects(object, other, equalFunc, customizer, bitmask, stack);
+    stack.pop();
+    return result;
+  }
+
+  /**
+   * The base implementation of `_.iteratee`.
+   *
+   * @private
+   * @param {*} [value=_.identity] The value to convert to an iteratee.
+   * @returns {Function} Returns the iteratee.
+   */
+  function baseIteratee(func) {
+    if (typeof func == 'function') {
+      return func;
+    }
+    if (func == null) {
+      return identity;
+    }
+    return (typeof func == 'object' ? baseMatches : baseProperty)(func);
+  }
+
+  /**
+   * The base implementation of `_.keys` which doesn't skip the constructor
+   * property of prototypes or treat sparse arrays as dense.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @returns {Array} Returns the array of property names.
+   */
+  function baseKeys(object) {
+    return nativeKeys(Object(object));
+  }
+
+  /**
+   * The base implementation of `_.keysIn` which doesn't skip the constructor
+   * property of prototypes or treat sparse arrays as dense.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @returns {Array} Returns the array of property names.
+   */
+  function baseKeysIn(object) {
+    object = object == null ? object : Object(object);
+
+    var result = [];
+    for (var key in object) {
+      result.push(key);
+    }
+    return result;
+  }
+
+  // Fallback for IE < 9 with es6-shim.
+  if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
+    baseKeysIn = function(object) {
+      return iteratorToArray(enumerate(object));
+    };
+  }
+
+  /**
+   * The base implementation of `_.lt` which doesn't coerce arguments to numbers.
+   *
+   * @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 function.
+   */
+  function baseMatches(source) {
+    var props = keys(source);
+    return function(object) {
+      var length = props.length;
+      if (object == null) {
+        return !length;
+      }
+      object = Object(object);
+      while (length--) {
+        var key = props[length];
+        if (!(key in object &&
+              baseIsEqual(source[key], object[key], undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG)
+            )) {
+          return false;
+        }
+      }
+      return true;
+    };
+  }
+
+  /**
+   * The base implementation of `_.pick` without support for individual
+   * property identifiers.
+   *
+   * @private
+   * @param {Object} object The source object.
+   * @param {string[]} props The property identifiers to pick.
+   * @returns {Object} Returns the new object.
+   */
+  function basePick(object, props) {
+    object = Object(object);
+    return reduce(props, function(result, key) {
+      if (key in object) {
+        result[key] = object[key];
+      }
+      return result;
+    }, {});
+  }
+
+  /**
+   * 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 function.
+   */
+  function baseProperty(key) {
+    return function(object) {
+      return object == null ? undefined : object[key];
+    };
+  }
+
+  /**
+   * 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;
+  }
+
+  /**
+   * 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) {
+    return baseSlice(source, 0, source.length);
+  }
+
+  /**
+   * 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 `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;
+    return reduce(actions, function(result, action) {
+      return action.func.apply(action.thisArg, arrayPush([result], action.args));
+    }, result);
+  }
+
+  /**
+   * 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 = false;
+
+      var othIsDefined = other !== undefined,
+          othIsNull = other === null,
+          othIsReflexive = other === other,
+          othIsSymbol = false;
+
+      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;
+  }
+
+  /**
+   * 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) {
+    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)
+        : source[key];
+
+      assignValue(object, key, newValue);
+    }
+    return object;
+  }
+
+  /**
+   * 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 rest(function(object, sources) {
+      var index = -1,
+          length = sources.length,
+          customizer = length > 1 ? sources[length - 1] : undefined;
+
+      customizer = typeof customizer == 'function'
+        ? (length--, customizer)
+        : undefined;
+
+      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 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 createCtorWrapper(Ctor) {
+    return function() {
+      // Use a `switch` statement to work with class constructors. See
+      // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
+      // for more details.
+      var args = arguments;
+      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 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 of wrapper flags. See `createWrapper`
+   *  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 createPartialWrapper(func, bitmask, thisArg, partials) {
+    if (typeof func != 'function') {
+      throw new TypeError(FUNC_ERROR_TEXT);
+    }
+    var isBind = bitmask & BIND_FLAG,
+        Ctor = createCtorWrapper(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 fn.apply(isBind ? thisArg : this, args);
+    }
+    return wrapper;
+  }
+
+  /**
+   * 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 {Function} equalFunc The function to determine equivalents of values.
+   * @param {Function} customizer The function to customize comparisons.
+   * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+   *  for more details.
+   * @param {Object} stack Tracks traversed `array` and `other` objects.
+   * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+   */
+  function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
+    var index = -1,
+        isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+        isUnordered = bitmask & UNORDERED_COMPARE_FLAG,
+        arrLength = array.length,
+        othLength = other.length;
+
+    if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
+      return false;
+    }
+    var result = true;
+
+    // Ignore non-index properties.
+    while (++index < arrLength) {
+      var arrValue = array[index],
+          othValue = other[index];
+
+      var compared;
+      if (compared !== undefined) {
+        if (compared) {
+          continue;
+        }
+        result = false;
+        break;
+      }
+      // Recursively compare arrays (susceptible to call stack limits).
+      if (isUnordered) {
+        if (!baseSome(other, function(othValue) {
+              return arrValue === othValue ||
+                equalFunc(arrValue, othValue, customizer, bitmask, stack);
+            })) {
+          result = false;
+          break;
+        }
+      } else if (!(
+            arrValue === othValue ||
+              equalFunc(arrValue, othValue, customizer, bitmask, stack)
+          )) {
+        result = false;
+        break;
+      }
+    }
+    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 {Function} equalFunc The function to determine equivalents of values.
+   * @param {Function} customizer The function to customize comparisons.
+   * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+   *  for more details.
+   * @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, equalFunc, customizer, bitmask, stack) {
+    switch (tag) {
+
+      case boolTag:
+      case dateTag:
+        // Coerce dates and booleans to numbers, dates to milliseconds and
+        // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
+        // not equal.
+        return +object == +other;
+
+      case errorTag:
+        return object.name == other.name && object.message == other.message;
+
+      case numberTag:
+        // Treat `NaN` vs. `NaN` as equal.
+        return (object != +object) ? other != +other : object == +other;
+
+      case regexpTag:
+      case stringTag:
+        // Coerce regexes to strings and treat strings, primitives and objects,
+        // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
+        // for more details.
+        return object == (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 {Function} equalFunc The function to determine equivalents of values.
+   * @param {Function} customizer The function to customize comparisons.
+   * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+   *  for more details.
+   * @param {Object} stack Tracks traversed `object` and `other` objects.
+   * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+   */
+  function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
+    var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+        objProps = keys(object),
+        objLength = objProps.length,
+        othProps = keys(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;
+      }
+    }
+    var result = true;
+
+    var skipCtor = isPartial;
+    while (++index < objLength) {
+      key = objProps[index];
+      var objValue = object[key],
+          othValue = other[key];
+
+      var compared;
+      // Recursively compare objects (susceptible to call stack limits).
+      if (!(compared === undefined
+            ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, 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;
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Gets the "length" property value of `object`.
+   *
+   * **Note:** This function is used to avoid a
+   * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
+   * Safari on at least iOS 8.1-8.3 ARM64.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @returns {*} Returns the "length" value.
+   */
+  var getLength = baseProperty('length');
+
+  /**
+   * Creates an array of index keys for `object` values of arrays,
+   * `arguments` objects, and strings, otherwise `null` is returned.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @returns {Array|null} Returns index keys, else `null`.
+   */
+  function indexKeys(object) {
+    var length = object ? object.length : undefined;
+    if (isLength(length) &&
+        (isArray(object) || isString(object) || isArguments(object))) {
+      return baseTimes(length, String);
+    }
+    return null;
+  }
+
+  /**
+   * 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 isArrayLikeObject(value) && (isArray(value) || isArguments(value));
+  }
+
+  /**
+   * 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 `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;
+  }
+
+  /**
+   * 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.
+   */
+  var toKey = String;
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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) {
+    return baseFilter(array, Boolean);
+  }
+
+  /**
+   * 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,
+        array = castArray(arguments[0]);
+
+    if (length < 2) {
+      return length ? copyArray(array) : [];
+    }
+    var args = Array(length - 1);
+    while (length--) {
+      args[length - 1] = arguments[length];
+    }
+    return arrayConcat(array, baseFlatten(args, 1));
+  }
+
+  /**
+   * 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 ? array.length : 0;
+    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 ? array.length : 0;
+    return length ? baseFlatten(array, INFINITY) : [];
+  }
+
+  /**
+   * 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/6.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 search.
+   * @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 ? array.length : 0;
+    if (typeof fromIndex == 'number') {
+      fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex;
+    } else {
+      fromIndex = 0;
+    }
+    var index = (fromIndex || 0) - 1,
+        isReflexive = value === value;
+
+    while (++index < length) {
+      var other = array[index];
+      if ((isReflexive ? other === value : other !== other)) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * 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 ? array.length : 0;
+    return length ? array[length - 1] : undefined;
+  }
+
+  /**
+   * 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 ? array.length : 0;
+    start = start == null ? 0 : +start;
+    end = end === undefined ? length : +end;
+    return length ? baseSlice(array, start, end) : [];
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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);
+  }
+
+  /**
+   * 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 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__);
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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).
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Collection
+   * @param {Array|Object} collection The collection to iterate over.
+   * @param {Array|Function|Object|string} [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) {
+    predicate = guard ? undefined : predicate;
+    return baseEvery(collection, baseIteratee(predicate));
+  }
+
+  /**
+   * 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).
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Collection
+   * @param {Array|Object} collection The collection to iterate over.
+   * @param {Array|Function|Object|string} [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) {
+    return baseFilter(collection, baseIteratee(predicate));
+  }
+
+  /**
+   * 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 search.
+   * @param {Array|Function|Object|string} [predicate=_.identity]
+   *  The function invoked per iteration.
+   * @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'
+   */
+  function find(collection, predicate) {
+    return baseFind(collection, baseIteratee(predicate), baseEach);
+  }
+
+  /**
+   * 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
+   *
+   * _([1, 2]).forEach(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) {
+    return baseEach(collection, baseIteratee(iteratee));
+  }
+
+  /**
+   * 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 {Array|Function|Object|string} [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) {
+    return baseMap(collection, baseIteratee(iteratee));
+  }
+
+  /**
+   * 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) {
+    return baseReduce(collection, baseIteratee(iteratee), accumulator, arguments.length < 3, baseEach);
+  }
+
+  /**
+   * 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} 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;
+    }
+    collection = isArrayLike(collection) ? collection : keys(collection);
+    return 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 {Array|Function|Object|string} [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) {
+    predicate = guard ? undefined : predicate;
+    return baseSome(collection, baseIteratee(predicate));
+  }
+
+  /**
+   * 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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+   *  [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]]
+   *
+   * _.sortBy(users, 'user', function(o) {
+   *   return Math.floor(o.age / 10);
+   * });
+   * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+   */
+  function sortBy(collection, iteratee) {
+    var index = 0;
+    iteratee = baseIteratee(iteratee);
+
+    return baseMap(baseMap(collection, function(value, key, collection) {
+      return { 'value': value, 'index': index++, 'criteria': iteratee(value, key, collection) };
+    }).sort(function(object, other) {
+      return compareAscending(object.criteria, other.criteria) || (object.index - other.index);
+    }), baseProperty('value'));
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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
+   *
+   * var greet = function(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 = rest(function(func, thisArg, partials) {
+    return createPartialWrapper(func, BIND_FLAG | PARTIAL_FLAG, thisArg, partials);
+  });
+
+  /**
+   * 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 or more milliseconds.
+   */
+  var defer = rest(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 = rest(function(func, wait, args) {
+    return baseDelay(func, toNumber(wait) || 0, args);
+  });
+
+  /**
+   * 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 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() {
+      return !predicate.apply(this, arguments);
+    };
+  }
+
+  /**
+   * 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();
+   * // `initialize` invokes `createApplication` once
+   */
+  function once(func) {
+    return before(2, func);
+  }
+
+  /**
+   * 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 = nativeMax(start === undefined ? (func.length - 1) : toInteger(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];
+      }
+      var otherArgs = Array(start + 1);
+      index = -1;
+      while (++index < start) {
+        otherArgs[index] = args[index];
+      }
+      otherArgs[start] = array;
+      return func.apply(this, otherArgs);
+    };
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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) {
+    if (!isObject(value)) {
+      return value;
+    }
+    return isArray(value) ? copyArray(value) : copyObject(value, keys(value));
+  }
+
+  /**
+   * Performs a
+   * [`SameValueZero`](http://ecma-international.org/ecma-262/6.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 = { 'user': 'fred' };
+   * var other = { 'user': 'fred' };
+   *
+   * _.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 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 correctly classified,
+   *  else `false`.
+   * @example
+   *
+   * _.isArguments(function() { return arguments; }());
+   * // => true
+   *
+   * _.isArguments([1, 2, 3]);
+   * // => false
+   */
+  function isArguments(value) {
+    // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+    return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+      (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+  }
+
+  /**
+   * Checks if `value` is classified as an `Array` object.
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @type {Function}
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is correctly classified,
+   *  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 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(getLength(value)) && !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 correctly classified,
+   *  else `false`.
+   * @example
+   *
+   * _.isBoolean(false);
+   * // => true
+   *
+   * _.isBoolean(null);
+   * // => false
+   */
+  function isBoolean(value) {
+    return value === true || value === false ||
+      (isObjectLike(value) && objectToString.call(value) == boolTag);
+  }
+
+  /**
+   * 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 correctly classified,
+   *  else `false`.
+   * @example
+   *
+   * _.isDate(new Date);
+   * // => true
+   *
+   * _.isDate('Mon April 23 2012');
+   * // => false
+   */
+  function isDate(value) {
+    return isObjectLike(value) && objectToString.call(value) == dateTag;
+  }
+
+  /**
+   * 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 (isArrayLike(value) &&
+        (isArray(value) || isString(value) ||
+          isFunction(value.splice) || isArguments(value))) {
+      return !value.length;
+    }
+    return !keys(value).length;
+  }
+
+  /**
+   * 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 **not** supported.
+   *
+   * @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 = { 'user': 'fred' };
+   * var other = { 'user': 'fred' };
+   *
+   * _.isEqual(object, other);
+   * // => true
+   *
+   * object === other;
+   * // => false
+   */
+  function isEqual(value, other) {
+    return baseIsEqual(value, other);
+  }
+
+  /**
+   * 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.MAX_VALUE);
+   * // => true
+   *
+   * _.isFinite(3.14);
+   * // => true
+   *
+   * _.isFinite(Infinity);
+   * // => 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 correctly classified,
+   *  else `false`.
+   * @example
+   *
+   * _.isFunction(_);
+   * // => true
+   *
+   * _.isFunction(/abc/);
+   * // => false
+   */
+  function isFunction(value) {
+    // The use of `Object#toString` avoids issues with the `typeof` operator
+    // in Safari 8 which returns 'object' for typed array and weak map constructors,
+    // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+    var tag = isObject(value) ? objectToString.call(value) : '';
+    return tag == funcTag || tag == genTag;
+  }
+
+  /**
+   * Checks if `value` is a valid array-like length.
+   *
+   * **Note:** This function is loosely based on
+   * [`ToLength`](http://ecma-international.org/ecma-262/6.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/6.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 && (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 && typeof value == 'object';
+  }
+
+  /**
+   * 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 `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 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 correctly classified,
+   *  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) && objectToString.call(value) == numberTag);
+  }
+
+  /**
+   * 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 correctly classified,
+   *  else `false`.
+   * @example
+   *
+   * _.isRegExp(/abc/);
+   * // => true
+   *
+   * _.isRegExp('/abc/');
+   * // => false
+   */
+  function isRegExp(value) {
+    return isObject(value) && objectToString.call(value) == regexpTag;
+  }
+
+  /**
+   * 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 correctly classified,
+   *  else `false`.
+   * @example
+   *
+   * _.isString('abc');
+   * // => true
+   *
+   * _.isString(1);
+   * // => false
+   */
+  function isString(value) {
+    return typeof value == 'string' ||
+      (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
+  }
+
+  /**
+   * 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;
+  }
+
+  /**
+   * 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 (!isArrayLike(value)) {
+      return values(value);
+    }
+    return value.length ? copyArray(value) : [];
+  }
+
+  /**
+   * Converts `value` to an integer.
+   *
+   * **Note:** This function is loosely based on
+   * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.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);
+   * // => 3
+   *
+   * _.toInteger(Number.MIN_VALUE);
+   * // => 0
+   *
+   * _.toInteger(Infinity);
+   * // => 1.7976931348623157e+308
+   *
+   * _.toInteger('3');
+   * // => 3
+   */
+  var toInteger = Number;
+
+  /**
+   * 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);
+   * // => 3
+   *
+   * _.toNumber(Number.MIN_VALUE);
+   * // => 5e-324
+   *
+   * _.toNumber(Infinity);
+   * // => Infinity
+   *
+   * _.toNumber('3');
+   * // => 3
+   */
+  var toNumber = Number;
+
+  /**
+   * 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 process.
+   * @returns {string} Returns the string.
+   * @example
+   *
+   * _.toString(null);
+   * // => ''
+   *
+   * _.toString(-0);
+   * // => '-0'
+   *
+   * _.toString([1, 2, 3]);
+   * // => '1,2,3'
+   */
+  function toString(value) {
+    if (typeof value == 'string') {
+      return value;
+    }
+    return value == null ? '' : (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.c = 3;
+   * }
+   *
+   * function Bar() {
+   *   this.e = 5;
+   * }
+   *
+   * Foo.prototype.d = 4;
+   * Bar.prototype.f = 6;
+   *
+   * _.assign({ 'a': 1 }, new Foo, new Bar);
+   * // => { 'a': 1, 'c': 3, 'e': 5 }
+   */
+  var assign = createAssigner(function(object, source) {
+    copyObject(source, keys(source), object);
+  });
+
+  /**
+   * 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.b = 2;
+   * }
+   *
+   * function Bar() {
+   *   this.d = 4;
+   * }
+   *
+   * Foo.prototype.c = 3;
+   * Bar.prototype.e = 5;
+   *
+   * _.assignIn({ 'a': 1 }, new Foo, new Bar);
+   * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
+   */
+  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);
+  });
+
+  /**
+   * 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 ? assign(result, properties) : result;
+  }
+
+  /**
+   * 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({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+   * // => { 'user': 'barney', 'age': 36 }
+   */
+  var defaults = rest(function(args) {
+    args.push(undefined, assignInDefaults);
+    return assignInWith.apply(undefined, args);
+  });
+
+  /**
+   * 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 && hasOwnProperty.call(object, path);
+  }
+
+  /**
+   * 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/6.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) {
+    var isProto = isPrototype(object);
+    if (!(isProto || isArrayLike(object))) {
+      return baseKeys(object);
+    }
+    var indexes = indexKeys(object),
+        skipIndexes = !!indexes,
+        result = indexes || [],
+        length = result.length;
+
+    for (var key in object) {
+      if (hasOwnProperty.call(object, key) &&
+          !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+          !(isProto && key == 'constructor')) {
+        result.push(key);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * 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) {
+    var index = -1,
+        isProto = isPrototype(object),
+        props = baseKeysIn(object),
+        propsLength = props.length,
+        indexes = indexKeys(object),
+        skipIndexes = !!indexes,
+        result = indexes || [],
+        length = result.length;
+
+    while (++index < propsLength) {
+      var key = props[index];
+      if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+          !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+        result.push(key);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * 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[])} [props] The property identifiers 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 = rest(function(object, props) {
+    return object == null ? {} : basePick(object, baseMap(baseFlatten(props, 1), toKey));
+  });
+
+  /**
+   * 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) {
+    var value = object == null ? undefined : object[path];
+    if (value === undefined) {
+      value = defaultValue;
+    }
+    return isFunction(value) ? value.call(object) : value;
+  }
+
+  /**
+   * 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 ? baseValues(object, keys(object)) : [];
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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.
+   *
+   * Backticks are escaped because in IE < 9, they can break out of
+   * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+   * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
+   * [#133](https://html5sec.org/#133) of the
+   * [HTML5 Security Cheatsheet](https://html5sec.org/) 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;
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * This method returns the first argument given to it.
+   *
+   * @static
+   * @since 0.1.0
+   * @memberOf _
+   * @category Util
+   * @param {*} value Any value.
+   * @returns {*} Returns `value`.
+   * @example
+   *
+   * var object = { 'user': 'fred' };
+   *
+   * _.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']
+   */
+  var iteratee = baseIteratee;
+
+  /**
+   * 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`. The created function is equivalent to
+   * `_.isMatch` with a `source` partially applied.
+   *
+   * **Note:** This method supports comparing the same values as `_.isEqual`.
+   *
+   * @static
+   * @memberOf _
+   * @since 3.0.0
+   * @category Util
+   * @param {Object} source The object of property values to match.
+   * @returns {Function} Returns the new function.
+   * @example
+   *
+   * var users = [
+   *   { 'user': 'barney', 'age': 36, 'active': true },
+   *   { 'user': 'fred',   'age': 40, 'active': false }
+   * ];
+   *
+   * _.filter(users, _.matches({ 'age': 40, 'active': false }));
+   * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
+   */
+  function matches(source) {
+    return baseMatches(assign({}, source));
+  }
+
+  /**
+   * 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);
+
+    baseEach(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;
+  }
+
+  /**
+   * A no-operation function that returns `undefined` regardless of the
+   * arguments it receives.
+   *
+   * @static
+   * @memberOf _
+   * @since 2.3.0
+   * @category Util
+   * @example
+   *
+   * var object = { 'user': 'fred' };
+   *
+   * _.noop(object) === undefined;
+   * // => true
+   */
+  function noop() {
+    // No operation performed.
+  }
+
+  /**
+   * 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;
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  /**
+   * 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;
+  }
+
+  /**
+   * 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;
+  }
+
+  /*------------------------------------------------------------------------*/
+
+  // Add methods that return wrapped values in chain sequences.
+  lodash.assignIn = assignIn;
+  lodash.before = before;
+  lodash.bind = bind;
+  lodash.chain = chain;
+  lodash.compact = compact;
+  lodash.concat = concat;
+  lodash.create = create;
+  lodash.defaults = defaults;
+  lodash.defer = defer;
+  lodash.delay = delay;
+  lodash.filter = filter;
+  lodash.flatten = flatten;
+  lodash.flattenDeep = flattenDeep;
+  lodash.iteratee = iteratee;
+  lodash.keys = keys;
+  lodash.map = map;
+  lodash.matches = matches;
+  lodash.mixin = mixin;
+  lodash.negate = negate;
+  lodash.once = once;
+  lodash.pick = pick;
+  lodash.slice = slice;
+  lodash.sortBy = sortBy;
+  lodash.tap = tap;
+  lodash.thru = thru;
+  lodash.toArray = toArray;
+  lodash.values = values;
+
+  // Add aliases.
+  lodash.extend = assignIn;
+
+  // Add methods to `lodash.prototype`.
+  mixin(lodash, lodash);
+
+  /*------------------------------------------------------------------------*/
+
+  // Add methods that return unwrapped values in chain sequences.
+  lodash.clone = clone;
+  lodash.escape = escape;
+  lodash.every = every;
+  lodash.find = find;
+  lodash.forEach = forEach;
+  lodash.has = has;
+  lodash.head = head;
+  lodash.identity = identity;
+  lodash.indexOf = indexOf;
+  lodash.isArguments = isArguments;
+  lodash.isArray = isArray;
+  lodash.isBoolean = isBoolean;
+  lodash.isDate = isDate;
+  lodash.isEmpty = isEmpty;
+  lodash.isEqual = isEqual;
+  lodash.isFinite = isFinite;
+  lodash.isFunction = isFunction;
+  lodash.isNaN = isNaN;
+  lodash.isNull = isNull;
+  lodash.isNumber = isNumber;
+  lodash.isObject = isObject;
+  lodash.isRegExp = isRegExp;
+  lodash.isString = isString;
+  lodash.isUndefined = isUndefined;
+  lodash.last = last;
+  lodash.max = max;
+  lodash.min = min;
+  lodash.noConflict = noConflict;
+  lodash.noop = noop;
+  lodash.reduce = reduce;
+  lodash.result = result;
+  lodash.size = size;
+  lodash.some = some;
+  lodash.uniqueId = uniqueId;
+
+  // Add aliases.
+  lodash.each = forEach;
+  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;
+
+  // Add `Array` methods to `lodash.prototype`.
+  baseEach(['pop', 'join', 'replace', 'reverse', 'split', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) {
+    var func = (/^(?:replace|split)$/.test(methodName) ? String.prototype : arrayProto)[methodName],
+        chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru',
+        retUnwrapped = /^(?:pop|join|replace|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);
+      });
+    };
+  });
+
+  // Add chain sequence methods to the `lodash` wrapper.
+  lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue;
+
+  /*--------------------------------------------------------------------------*/
+
+  // Expose Lodash on the free variable `window` or `self` when available so it's
+  // globally accessible, even when bundled with Browserify, Webpack, etc. This
+  // also prevents errors in cases where 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.
+  (freeWindow || freeSelf || {})._ = lodash;
+
+  // Some AMD build optimizers like r.js check for condition patterns like the following:
+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+    // Define as an anonymous module so, through path mapping, it can be
+    // referenced as the "underscore" module.
+    define(function() {
+      return lodash;
+    });
+  }
+  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
+  else if (freeExports && freeModule) {
+    // Export for Node.js.
+    if (moduleExports) {
+      (freeModule.exports = lodash)._ = lodash;
+    }
+    // Export for CommonJS support.
+    freeExports._ = lodash;
+  }
+  else {
+    // Export to the global object.
+    root._ = lodash;
+  }
+}.call(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.core.min.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.core.min.js
new file mode 100644
index 0000000..af9a225
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.core.min.js
@@ -0,0 +1,30 @@
+/**
+ * @license
+ * lodash 4.11.2 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
+ * Build: `lodash core -o ./dist/lodash.core.js`
+ */
+;(function(){function n(n,t){return n.push.apply(n,t),n}function t(n,t,r){var e;return r(n,function(n,r,u){return t(n,r,u)?(e=n,false):void 0}),e}function r(n,t,r,e,u){return u(n,function(n,u,o){r=e?(e=false,n):t(r,n,u,o)}),r}function e(n,t){return O(t,function(t){return n[t]})}function u(n){return n&&n.Object===Object?n:null}function o(n){return gn[n]}function i(n){var t=false;if(null!=n&&typeof n.toString!="function")try{t=!!(n+"")}catch(r){}return t}function c(n){return n instanceof f?n:new f(n)}function f(n,t){
+this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function a(n,t,r,e){var u;return(u=n===pn)||(u=En[r],u=(n===u||n!==n&&u!==u)&&!kn.call(e,r)),u?t:n}function l(n){return nn(n)?Bn(n):{}}function p(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function");return setTimeout(function(){n.apply(pn,r)},t)}function s(n,t){var r=true;return zn(n,function(n,e,u){return r=!!t(n,e,u)}),r}function h(n,t,r){for(var e=-1,u=n.length;++e<u;){var o=n[e],i=t(o);if(null!=i&&(c===pn?i===i:r(i,c)))var c=i,f=o;
+}return f}function v(n,t){var r=[];return zn(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function y(t,r,e,u,o){var i=-1,c=t.length;for(e||(e=G),o||(o=[]);++i<c;){var f=t[i];r>0&&e(f)?r>1?y(f,r-1,e,u,o):n(o,f):u||(o[o.length]=f)}return o}function g(n,t){return n&&Cn(n,t,on)}function b(n,t){return v(t,function(t){return Y(n[t])})}function _(n,t){return n>t}function d(n,t,r,e,u){return n===t?true:null==n||null==t||!nn(n)&&!tn(t)?n!==n&&t!==t:j(n,t,d,r,e,u)}function j(n,t,r,e,u,o){var c=Vn(n),f=Vn(t),a="[object Array]",l="[object Array]";
+c||(a=Sn.call(n),a="[object Arguments]"==a?"[object Object]":a),f||(l=Sn.call(t),l="[object Arguments]"==l?"[object Object]":l);var p="[object Object]"==a&&!i(n),f="[object Object]"==l&&!i(t),l=a==l;o||(o=[]);var s=U(o,function(t){return t[0]===n});return s&&s[1]?s[1]==t:(o.push([n,t]),l&&!p?(r=c||isTypedArray(n)?$(n,t,r,e,u,o):q(n,t,a),o.pop(),r):2&u||(c=p&&kn.call(n,"__wrapped__"),a=f&&kn.call(t,"__wrapped__"),!c&&!a)?l?(r=z(n,t,r,e,u,o),o.pop(),r):false:(c=c?n.value():n,t=a?t.value():t,r=r(c,t,e,u,o),
+o.pop(),r))}function m(n){return typeof n=="function"?n:null==n?an:(typeof n=="object"?A:k)(n)}function w(n){n=null==n?n:Object(n);var t,r=[];for(t in n)r.push(t);return r}function x(n,t){return t>n}function O(n,t){var r=-1,e=X(n)?Array(n.length):[];return zn(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function A(n){var t=on(n);return function(r){var e=t.length;if(null==r)return!e;for(r=Object(r);e--;){var u=t[e];if(!(u in r&&d(n[u],r[u],pn,3)))return false}return true}}function E(n,t){return n=Object(n),H(t,function(t,r){
+return r in n&&(t[r]=n[r]),t},{})}function k(n){return function(t){return null==t?pn:t[n]}}function N(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e<u;)r[e]=n[e+t];return r}function S(n){return N(n,0,n.length)}function T(n,t){var r;return zn(n,function(n,e,u){return r=t(n,e,u),!r}),!!r}function F(t,r){return H(r,function(t,r){return r.func.apply(r.thisArg,n([t],r.args))},t)}function R(n,t,r,e){r||(r={});for(var u=-1,o=t.length;++u<o;){
+var i=t[u],c=e?e(r[i],n[i],i,r,n):n[i],f=r,a=f[i];kn.call(f,i)&&(a===c||a!==a&&c!==c)&&(c!==pn||i in f)||(f[i]=c)}return r}function B(n){return L(function(t,r){var e=-1,u=r.length,o=u>1?r[u-1]:pn,o=typeof o=="function"?(u--,o):pn;for(t=Object(t);++e<u;){var i=r[e];i&&n(t,i,e,o)}return t})}function D(n){return function(){var t=arguments,r=l(n.prototype),t=n.apply(r,t);return nn(t)?t:r}}function I(n,t,r){function e(){for(var o=-1,i=arguments.length,c=-1,f=r.length,a=Array(f+i),l=this&&this!==On&&this instanceof e?u:n;++c<f;)a[c]=r[c];
+for(;i--;)a[c++]=arguments[++o];return l.apply(t,a)}if(typeof n!="function")throw new TypeError("Expected a function");var u=D(n);return e}function $(n,t,r,e,u,o){var i=-1,c=1&u,f=n.length,a=t.length;if(f!=a&&!(2&u&&a>f))return false;for(a=true;++i<f;){var l=n[i],p=t[i];if(void 0!==pn){a=false;break}if(c){if(!T(t,function(n){return l===n||r(l,n,e,u,o)})){a=false;break}}else if(l!==p&&!r(l,p,e,u,o)){a=false;break}}return a}function q(n,t,r){switch(r){case"[object Boolean]":case"[object Date]":return+n==+t;case"[object Error]":
+return n.name==t.name&&n.message==t.message;case"[object Number]":return n!=+n?t!=+t:n==+t;case"[object RegExp]":case"[object String]":return n==t+""}return false}function z(n,t,r,e,u,o){var i=2&u,c=on(n),f=c.length,a=on(t).length;if(f!=a&&!i)return false;for(var l=f;l--;){var p=c[l];if(!(i?p in t:kn.call(t,p)))return false}for(a=true;++l<f;){var p=c[l],s=n[p],h=t[p];if(void 0!==pn||s!==h&&!r(s,h,e,u,o)){a=false;break}i||(i="constructor"==p)}return a&&!i&&(r=n.constructor,e=t.constructor,r!=e&&"constructor"in n&&"constructor"in t&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(a=false)),
+a}function C(n){var t=n?n.length:pn;if(Z(t)&&(Vn(n)||en(n)||W(n))){n=String;for(var r=-1,e=Array(t);++r<t;)e[r]=n(r);t=e}else t=null;return t}function G(n){return tn(n)&&X(n)&&(Vn(n)||W(n))}function J(n,t){return t=null==t?9007199254740991:t,!!t&&(typeof n=="number"||yn.test(n))&&n>-1&&0==n%1&&t>n}function M(n){var t=n&&n.constructor;return n===(typeof t=="function"&&t.prototype||En)}function P(n){return n&&n.length?n[0]:pn}function U(n,r){return t(n,m(r),zn)}function V(n,t){return zn(n,m(t))}function H(n,t,e){
+return r(n,m(t),e,3>arguments.length,zn)}function K(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Hn(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=pn),r}}function L(n){var t;if(typeof n!="function")throw new TypeError("Expected a function");return t=qn(t===pn?n.length-1:Hn(t),0),function(){for(var r=arguments,e=-1,u=qn(r.length-t,0),o=Array(u);++e<u;)o[e]=r[t+e];for(u=Array(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=o,n.apply(this,u)}}function Q(){
+if(!arguments.length)return[];var n=arguments[0];return Vn(n)?n:[n]}function W(n){return tn(n)&&X(n)&&kn.call(n,"callee")&&(!Dn.call(n,"callee")||"[object Arguments]"==Sn.call(n))}function X(n){return null!=n&&Z(Gn(n))&&!Y(n)}function Y(n){return n=nn(n)?Sn.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function Z(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function nn(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function tn(n){return!!n&&typeof n=="object";
+}function rn(n){return typeof n=="number"||tn(n)&&"[object Number]"==Sn.call(n)}function en(n){return typeof n=="string"||!Vn(n)&&tn(n)&&"[object String]"==Sn.call(n)}function un(n){return typeof n=="string"?n:null==n?"":n+""}function on(n){var t=M(n);if(!t&&!X(n))return $n(Object(n));var r,e=C(n),u=!!e,e=e||[],o=e.length;for(r in n)!kn.call(n,r)||u&&("length"==r||J(r,o))||t&&"constructor"==r||e.push(r);return e}function cn(n){for(var t=-1,r=M(n),e=w(n),u=e.length,o=C(n),i=!!o,o=o||[],c=o.length;++t<u;){
+var f=e[t];i&&("length"==f||J(f,c))||"constructor"==f&&(r||!kn.call(n,f))||o.push(f)}return o}function fn(n){return n?e(n,on(n)):[]}function an(n){return n}function ln(t,r,e){var u=on(r),o=b(r,u);null!=e||nn(r)&&(o.length||!u.length)||(e=r,r=t,t=this,o=b(r,on(r)));var i=!(nn(e)&&"chain"in e&&!e.chain),c=Y(t);return zn(o,function(e){var u=r[e];t[e]=u,c&&(t.prototype[e]=function(){var r=this.__chain__;if(i||r){var e=t(this.__wrapped__);return(e.__actions__=S(this.__actions__)).push({func:u,args:arguments,
+thisArg:t}),e.__chain__=r,e}return u.apply(t,n([this.value()],arguments))})}),t}var pn,sn=1/0,hn=/[&<>"'`]/g,vn=RegExp(hn.source),yn=/^(?:0|[1-9]\d*)$/,gn={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},bn={"function":true,object:true},_n=bn[typeof exports]&&exports&&!exports.nodeType?exports:pn,dn=bn[typeof module]&&module&&!module.nodeType?module:pn,jn=dn&&dn.exports===_n?_n:pn,mn=u(bn[typeof self]&&self),wn=u(bn[typeof window]&&window),xn=u(bn[typeof this]&&this),On=u(_n&&dn&&typeof global=="object"&&global)||wn!==(xn&&xn.window)&&wn||mn||xn||Function("return this")(),An=Array.prototype,En=Object.prototype,kn=En.hasOwnProperty,Nn=0,Sn=En.toString,Tn=On._,Fn=On.Reflect,Rn=Fn?Fn.a:pn,Bn=Object.create,Dn=En.propertyIsEnumerable,In=On.isFinite,$n=Object.keys,qn=Math.max;
+f.prototype=l(c.prototype),f.prototype.constructor=f;var zn=function(n,t){return function(r,e){if(null==r)return r;if(!X(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++o<u)&&false!==e(i[o],o,i););return r}}(g),Cn=function(n){return function(t,r,e){var u=-1,o=Object(t);e=e(t);for(var i=e.length;i--;){var c=e[n?i:++u];if(false===r(o[c],c,o))break}return t}}();Rn&&!Dn.call({valueOf:1},"valueOf")&&(w=function(n){n=Rn(n);for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r});var Gn=k("length"),Jn=String,Mn=L(function(n,t,r){
+return I(n,t,r)}),Pn=L(function(n,t){return p(n,1,t)}),Un=L(function(n,t,r){return p(n,Kn(t)||0,r)}),Vn=Array.isArray,Hn=Number,Kn=Number,Ln=B(function(n,t){R(t,on(t),n)}),Qn=B(function(n,t){R(t,cn(t),n)}),Wn=B(function(n,t,r,e){R(t,cn(t),n,e)}),Xn=L(function(n){return n.push(pn,a),Wn.apply(pn,n)}),Yn=L(function(n,t){return null==n?{}:E(n,O(y(t,1),Jn))}),Zn=m;c.assignIn=Qn,c.before=K,c.bind=Mn,c.chain=function(n){return n=c(n),n.__chain__=true,n},c.compact=function(n){return v(n,Boolean)},c.concat=function(){
+var t=arguments.length,r=Q(arguments[0]);if(2>t)return t?S(r):[];for(var e=Array(t-1);t--;)e[t-1]=arguments[t];return y(e,1),n(S(r),fn)},c.create=function(n,t){var r=l(n);return t?Ln(r,t):r},c.defaults=Xn,c.defer=Pn,c.delay=Un,c.filter=function(n,t){return v(n,m(t))},c.flatten=function(n){return n&&n.length?y(n,1):[]},c.flattenDeep=function(n){return n&&n.length?y(n,sn):[]},c.iteratee=Zn,c.keys=on,c.map=function(n,t){return O(n,m(t))},c.matches=function(n){return A(Ln({},n))},c.mixin=ln,c.negate=function(n){
+if(typeof n!="function")throw new TypeError("Expected a function");return function(){return!n.apply(this,arguments)}},c.once=function(n){return K(2,n)},c.pick=Yn,c.slice=function(n,t,r){var e=n?n.length:0;return r=r===pn?e:+r,e?N(n,null==t?0:+t,r):[]},c.sortBy=function(n,t){var r=0;return t=m(t),O(O(n,function(n,e,u){return{value:n,index:r++,criteria:t(n,e,u)}}).sort(function(n,t){var r;n:{r=n.criteria;var e=t.criteria;if(r!==e){var u=r!==pn,o=null===r,i=r===r,c=e!==pn,f=null===e,a=e===e;if(!f&&r>e||o&&c&&a||!u&&a||!i){
+r=1;break n}if(!o&&e>r||f&&u&&i||!c&&i||!a){r=-1;break n}}r=0}return r||n.index-t.index}),k("value"))},c.tap=function(n,t){return t(n),n},c.thru=function(n,t){return t(n)},c.toArray=function(n){return X(n)?n.length?S(n):[]:fn(n)},c.values=fn,c.extend=Qn,ln(c,c),c.clone=function(n){return nn(n)?Vn(n)?S(n):R(n,on(n)):n},c.escape=function(n){return(n=un(n))&&vn.test(n)?n.replace(hn,o):n},c.every=function(n,t,r){return t=r?pn:t,s(n,m(t))},c.find=U,c.forEach=V,c.has=function(n,t){return null!=n&&kn.call(n,t);
+},c.head=P,c.identity=an,c.indexOf=function(n,t,r){var e=n?n.length:0;r=typeof r=="number"?0>r?qn(e+r,0):r:0,r=(r||0)-1;for(var u=t===t;++r<e;){var o=n[r];if(u?o===t:o!==o)return r}return-1},c.isArguments=W,c.isArray=Vn,c.isBoolean=function(n){return true===n||false===n||tn(n)&&"[object Boolean]"==Sn.call(n)},c.isDate=function(n){return tn(n)&&"[object Date]"==Sn.call(n)},c.isEmpty=function(n){return X(n)&&(Vn(n)||en(n)||Y(n.splice)||W(n))?!n.length:!on(n).length},c.isEqual=function(n,t){return d(n,t)},
+c.isFinite=function(n){return typeof n=="number"&&In(n)},c.isFunction=Y,c.isNaN=function(n){return rn(n)&&n!=+n},c.isNull=function(n){return null===n},c.isNumber=rn,c.isObject=nn,c.isRegExp=function(n){return nn(n)&&"[object RegExp]"==Sn.call(n)},c.isString=en,c.isUndefined=function(n){return n===pn},c.last=function(n){var t=n?n.length:0;return t?n[t-1]:pn},c.max=function(n){return n&&n.length?h(n,an,_):pn},c.min=function(n){return n&&n.length?h(n,an,x):pn},c.noConflict=function(){return On._===this&&(On._=Tn),
+this},c.noop=function(){},c.reduce=H,c.result=function(n,t,r){return t=null==n?pn:n[t],t===pn&&(t=r),Y(t)?t.call(n):t},c.size=function(n){return null==n?0:(n=X(n)?n:on(n),n.length)},c.some=function(n,t,r){return t=r?pn:t,T(n,m(t))},c.uniqueId=function(n){var t=++Nn;return un(n)+t},c.each=V,c.first=P,ln(c,function(){var n={};return g(c,function(t,r){kn.call(c.prototype,r)||(n[r]=t)}),n}(),{chain:false}),c.VERSION="4.11.2",zn("pop join replace reverse split push shift sort splice unshift".split(" "),function(n){
+var t=(/^(?:replace|split)$/.test(n)?String.prototype:An)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|join|replace|shift)$/.test(n);c.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(Vn(u)?u:[],n)}return this[r](function(r){return t.apply(Vn(r)?r:[],n)})}}),c.prototype.toJSON=c.prototype.valueOf=c.prototype.value=function(){return F(this.__wrapped__,this.__actions__)},(wn||mn||{})._=c,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){
+return c}):_n&&dn?(jn&&((dn.exports=c)._=c),_n._=c):On._=c}).call(this);
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.fp.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.fp.js
new file mode 100644
index 0000000..6181b35
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.fp.js
@@ -0,0 +1,863 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["fp"] = factory();
+	else
+		root["fp"] = 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__) {
+
+	var baseConvert = __webpack_require__(1);
+
+	/**
+	 * Converts `lodash` to an immutable auto-curried iteratee-first data-last
+	 * version with conversion `options` applied.
+	 *
+	 * @param {Function} lodash The lodash function to convert.
+	 * @param {Object} [options] The options object. See `baseConvert` for more details.
+	 * @returns {Function} Returns the converted `lodash`.
+	 */
+	function browserConvert(lodash, options) {
+	  return baseConvert(lodash, lodash, options);
+	}
+
+	if (typeof _ == 'function') {
+	  _ = browserConvert(_.runInContext());
+	}
+	module.exports = browserConvert;
+
+
+/***/ },
+/* 1 */
+/***/ function(module, exports, __webpack_require__) {
+
+	var mapping = __webpack_require__(2),
+	    mutateMap = mapping.mutate,
+	    fallbackHolder = __webpack_require__(3);
+
+	/**
+	 * Creates a function, with an arity of `n`, that invokes `func` with the
+	 * arguments it receives.
+	 *
+	 * @private
+	 * @param {Function} func The function to wrap.
+	 * @param {number} n The arity of the new function.
+	 * @returns {Function} Returns the new function.
+	 */
+	function baseArity(func, n) {
+	  return n == 2
+	    ? function(a, b) { return func.apply(undefined, arguments); }
+	    : function(a) { return func.apply(undefined, arguments); };
+	}
+
+	/**
+	 * Creates a function that invokes `func`, with up to `n` arguments, ignoring
+	 * any additional arguments.
+	 *
+	 * @private
+	 * @param {Function} func The function to cap arguments for.
+	 * @param {number} n The arity cap.
+	 * @returns {Function} Returns the new function.
+	 */
+	function baseAry(func, n) {
+	  return n == 2
+	    ? function(a, b) { return func(a, b); }
+	    : function(a) { return func(a); };
+	}
+
+	/**
+	 * Creates a clone of `array`.
+	 *
+	 * @private
+	 * @param {Array} array The array to clone.
+	 * @returns {Array} Returns the cloned array.
+	 */
+	function cloneArray(array) {
+	  var length = array ? array.length : 0,
+	      result = Array(length);
+
+	  while (length--) {
+	    result[length] = array[length];
+	  }
+	  return result;
+	}
+
+	/**
+	 * Creates a function that clones a given object using the assignment `func`.
+	 *
+	 * @private
+	 * @param {Function} func The assignment function.
+	 * @returns {Function} Returns the new cloner function.
+	 */
+	function createCloner(func) {
+	  return function(object) {
+	    return func({}, object);
+	  };
+	}
+
+	/**
+	 * Creates a function that wraps `func` and uses `cloner` to clone the first
+	 * argument it receives.
+	 *
+	 * @private
+	 * @param {Function} func The function to wrap.
+	 * @param {Function} cloner The function to clone arguments.
+	 * @returns {Function} Returns the new immutable function.
+	 */
+	function immutWrap(func, cloner) {
+	  return function() {
+	    var length = arguments.length;
+	    if (!length) {
+	      return result;
+	    }
+	    var args = Array(length);
+	    while (length--) {
+	      args[length] = arguments[length];
+	    }
+	    var result = args[0] = cloner.apply(undefined, args);
+	    func.apply(undefined, args);
+	    return result;
+	  };
+	}
+
+	/**
+	 * The base implementation of `convert` which accepts a `util` object of methods
+	 * required to perform conversions.
+	 *
+	 * @param {Object} util The util object.
+	 * @param {string} name The name of the function to convert.
+	 * @param {Function} func The function to convert.
+	 * @param {Object} [options] The options object.
+	 * @param {boolean} [options.cap=true] Specify capping iteratee arguments.
+	 * @param {boolean} [options.curry=true] Specify currying.
+	 * @param {boolean} [options.fixed=true] Specify fixed arity.
+	 * @param {boolean} [options.immutable=true] Specify immutable operations.
+	 * @param {boolean} [options.rearg=true] Specify rearranging arguments.
+	 * @returns {Function|Object} Returns the converted function or object.
+	 */
+	function baseConvert(util, name, func, options) {
+	  var setPlaceholder,
+	      isLib = typeof name == 'function',
+	      isObj = name === Object(name);
+
+	  if (isObj) {
+	    options = func;
+	    func = name;
+	    name = undefined;
+	  }
+	  if (func == null) {
+	    throw new TypeError;
+	  }
+	  options || (options = {});
+
+	  var config = {
+	    'cap': 'cap' in options ? options.cap : true,
+	    'curry': 'curry' in options ? options.curry : true,
+	    'fixed': 'fixed' in options ? options.fixed : true,
+	    'immutable': 'immutable' in options ? options.immutable : true,
+	    'rearg': 'rearg' in options ? options.rearg : true
+	  };
+
+	  var forceCurry = ('curry' in options) && options.curry,
+	      forceFixed = ('fixed' in options) && options.fixed,
+	      forceRearg = ('rearg' in options) && options.rearg,
+	      placeholder = isLib ? func : fallbackHolder,
+	      pristine = isLib ? func.runInContext() : undefined;
+
+	  var helpers = isLib ? func : {
+	    'ary': util.ary,
+	    'assign': util.assign,
+	    'clone': util.clone,
+	    'curry': util.curry,
+	    'forEach': util.forEach,
+	    'isArray': util.isArray,
+	    'isFunction': util.isFunction,
+	    'iteratee': util.iteratee,
+	    'keys': util.keys,
+	    'rearg': util.rearg,
+	    'spread': util.spread,
+	    'toPath': util.toPath
+	  };
+
+	  var ary = helpers.ary,
+	      assign = helpers.assign,
+	      clone = helpers.clone,
+	      curry = helpers.curry,
+	      each = helpers.forEach,
+	      isArray = helpers.isArray,
+	      isFunction = helpers.isFunction,
+	      keys = helpers.keys,
+	      rearg = helpers.rearg,
+	      spread = helpers.spread,
+	      toPath = helpers.toPath;
+
+	  var aryMethodKeys = keys(mapping.aryMethod);
+
+	  var wrappers = {
+	    'castArray': function(castArray) {
+	      return function() {
+	        var value = arguments[0];
+	        return isArray(value)
+	          ? castArray(cloneArray(value))
+	          : castArray.apply(undefined, arguments);
+	      };
+	    },
+	    'iteratee': function(iteratee) {
+	      return function() {
+	        var func = arguments[0],
+	            arity = arguments[1],
+	            result = iteratee(func, arity),
+	            length = result.length;
+
+	        if (config.cap && typeof arity == 'number') {
+	          arity = arity > 2 ? (arity - 2) : 1;
+	          return (length && length <= arity) ? result : baseAry(result, arity);
+	        }
+	        return result;
+	      };
+	    },
+	    'mixin': function(mixin) {
+	      return function(source) {
+	        var func = this;
+	        if (!isFunction(func)) {
+	          return mixin(func, Object(source));
+	        }
+	        var methods = [],
+	            methodNames = [];
+
+	        each(keys(source), function(key) {
+	          var value = source[key];
+	          if (isFunction(value)) {
+	            methodNames.push(key);
+	            methods.push(func.prototype[key]);
+	          }
+	        });
+
+	        mixin(func, Object(source));
+
+	        each(methodNames, function(methodName, index) {
+	          var method = methods[index];
+	          if (isFunction(method)) {
+	            func.prototype[methodName] = method;
+	          } else {
+	            delete func.prototype[methodName];
+	          }
+	        });
+	        return func;
+	      };
+	    },
+	    'runInContext': function(runInContext) {
+	      return function(context) {
+	        return baseConvert(util, runInContext(context), options);
+	      };
+	    }
+	  };
+
+	  /*--------------------------------------------------------------------------*/
+
+	  /**
+	   * Creates a clone of `object` by `path`.
+	   *
+	   * @private
+	   * @param {Object} object The object to clone.
+	   * @param {Array|string} path The path to clone by.
+	   * @returns {Object} Returns the cloned object.
+	   */
+	  function cloneByPath(object, path) {
+	    path = toPath(path);
+
+	    var index = -1,
+	        length = path.length,
+	        result = clone(Object(object)),
+	        nested = result;
+
+	    while (nested != null && ++index < length) {
+	      var key = path[index],
+	          value = nested[key];
+
+	      if (value != null) {
+	        nested[key] = clone(Object(value));
+	      }
+	      nested = nested[key];
+	    }
+	    return result;
+	  }
+
+	  /**
+	   * Converts `lodash` to an immutable auto-curried iteratee-first data-last
+	   * version with conversion `options` applied.
+	   *
+	   * @param {Object} [options] The options object. See `baseConvert` for more details.
+	   * @returns {Function} Returns the converted `lodash`.
+	   */
+	  function convertLib(options) {
+	    return _.runInContext.convert(options)(undefined);
+	  }
+
+	  /**
+	   * Create a converter function for `func` of `name`.
+	   *
+	   * @param {string} name The name of the function to convert.
+	   * @param {Function} func The function to convert.
+	   * @returns {Function} Returns the new converter function.
+	   */
+	  function createConverter(name, func) {
+	    var oldOptions = options;
+	    return function(options) {
+	      var newUtil = isLib ? pristine : helpers,
+	          newFunc = isLib ? pristine[name] : func,
+	          newOptions = assign(assign({}, oldOptions), options);
+
+	      return baseConvert(newUtil, name, newFunc, newOptions);
+	    };
+	  }
+
+	  /**
+	   * Creates a function that wraps `func` to invoke its iteratee, with up to `n`
+	   * arguments, ignoring any additional arguments.
+	   *
+	   * @private
+	   * @param {Function} func The function to cap iteratee arguments for.
+	   * @param {number} n The arity cap.
+	   * @returns {Function} Returns the new function.
+	   */
+	  function iterateeAry(func, n) {
+	    return overArg(func, function(func) {
+	      return typeof func == 'function' ? baseAry(func, n) : func;
+	    });
+	  }
+
+	  /**
+	   * Creates a function that wraps `func` to invoke its iteratee 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.
+	   *
+	   * @private
+	   * @param {Function} func The function to rearrange iteratee arguments for.
+	   * @param {number[]} indexes The arranged argument indexes.
+	   * @returns {Function} Returns the new function.
+	   */
+	  function iterateeRearg(func, indexes) {
+	    return overArg(func, function(func) {
+	      var n = indexes.length;
+	      return baseArity(rearg(baseAry(func, n), indexes), n);
+	    });
+	  }
+
+	  /**
+	   * Creates a function that invokes `func` with its first argument passed
+	   * thru `transform`.
+	   *
+	   * @private
+	   * @param {Function} func The function to wrap.
+	   * @param {...Function} transform The functions to transform the first argument.
+	   * @returns {Function} Returns the new function.
+	   */
+	  function overArg(func, transform) {
+	    return function() {
+	      var length = arguments.length;
+	      if (!length) {
+	        return func();
+	      }
+	      var args = Array(length);
+	      while (length--) {
+	        args[length] = arguments[length];
+	      }
+	      var index = config.rearg ? 0 : (length - 1);
+	      args[index] = transform(args[index]);
+	      return func.apply(undefined, args);
+	    };
+	  }
+
+	  /**
+	   * Creates a function that wraps `func` and applys the conversions
+	   * rules by `name`.
+	   *
+	   * @private
+	   * @param {string} name The name of the function to wrap.
+	   * @param {Function} func The function to wrap.
+	   * @returns {Function} Returns the converted function.
+	   */
+	  function wrap(name, func) {
+	    name = mapping.aliasToReal[name] || name;
+
+	    var result,
+	        wrapped = func,
+	        wrapper = wrappers[name];
+
+	    if (wrapper) {
+	      wrapped = wrapper(func);
+	    }
+	    else if (config.immutable) {
+	      if (mutateMap.array[name]) {
+	        wrapped = immutWrap(func, cloneArray);
+	      }
+	      else if (mutateMap.object[name]) {
+	        wrapped = immutWrap(func, createCloner(func));
+	      }
+	      else if (mutateMap.set[name]) {
+	        wrapped = immutWrap(func, cloneByPath);
+	      }
+	    }
+	    each(aryMethodKeys, function(aryKey) {
+	      each(mapping.aryMethod[aryKey], function(otherName) {
+	        if (name == otherName) {
+	          var aryN = !isLib && mapping.iterateeAry[name],
+	              reargIndexes = mapping.iterateeRearg[name],
+	              spreadStart = mapping.methodSpread[name];
+
+	          result = wrapped;
+	          if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {
+	            result = spreadStart === undefined
+	              ? ary(result, aryKey)
+	              : spread(result, spreadStart);
+	          }
+	          if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
+	            result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
+	          }
+	          if (config.cap) {
+	            if (reargIndexes) {
+	              result = iterateeRearg(result, reargIndexes);
+	            } else if (aryN) {
+	              result = iterateeAry(result, aryN);
+	            }
+	          }
+	          if (forceCurry || (config.curry && aryKey > 1)) {
+	            forceCurry  && console.log(forceCurry, name);
+	            result = curry(result, aryKey);
+	          }
+	          return false;
+	        }
+	      });
+	      return !result;
+	    });
+
+	    result || (result = wrapped);
+	    if (result == func) {
+	      result = forceCurry ? curry(result, 1) : function() {
+	        return func.apply(this, arguments);
+	      };
+	    }
+	    result.convert = createConverter(name, func);
+	    if (mapping.placeholder[name]) {
+	      setPlaceholder = true;
+	      result.placeholder = func.placeholder = placeholder;
+	    }
+	    return result;
+	  }
+
+	  /*--------------------------------------------------------------------------*/
+
+	  if (!isObj) {
+	    return wrap(name, func);
+	  }
+	  var _ = func;
+
+	  // Convert methods by ary cap.
+	  var pairs = [];
+	  each(aryMethodKeys, function(aryKey) {
+	    each(mapping.aryMethod[aryKey], function(key) {
+	      var func = _[mapping.remap[key] || key];
+	      if (func) {
+	        pairs.push([key, wrap(key, func)]);
+	      }
+	    });
+	  });
+
+	  // Convert remaining methods.
+	  each(keys(_), function(key) {
+	    var func = _[key];
+	    if (typeof func == 'function') {
+	      var length = pairs.length;
+	      while (length--) {
+	        if (pairs[length][0] == key) {
+	          return;
+	        }
+	      }
+	      func.convert = createConverter(key, func);
+	      pairs.push([key, func]);
+	    }
+	  });
+
+	  // Assign to `_` leaving `_.prototype` unchanged to allow chaining.
+	  each(pairs, function(pair) {
+	    _[pair[0]] = pair[1];
+	  });
+
+	  _.convert = convertLib;
+	  if (setPlaceholder) {
+	    _.placeholder = placeholder;
+	  }
+	  // Assign aliases.
+	  each(keys(_), function(key) {
+	    each(mapping.realToAlias[key] || [], function(alias) {
+	      _[alias] = _[key];
+	    });
+	  });
+
+	  return _;
+	}
+
+	module.exports = baseConvert;
+
+
+/***/ },
+/* 2 */
+/***/ function(module, exports) {
+
+	/** Used to map aliases to their real names. */
+	exports.aliasToReal = {
+
+	  // Lodash aliases.
+	  'each': 'forEach',
+	  'eachRight': 'forEachRight',
+	  'entries': 'toPairs',
+	  'entriesIn': 'toPairsIn',
+	  'extend': 'assignIn',
+	  'extendWith': 'assignInWith',
+	  'first': 'head',
+
+	  // Ramda aliases.
+	  '__': 'placeholder',
+	  'all': 'every',
+	  'allPass': 'overEvery',
+	  'always': 'constant',
+	  'any': 'some',
+	  'anyPass': 'overSome',
+	  'apply': 'spread',
+	  'assoc': 'set',
+	  'assocPath': 'set',
+	  'complement': 'negate',
+	  'compose': 'flowRight',
+	  'contains': 'includes',
+	  'dissoc': 'unset',
+	  'dissocPath': 'unset',
+	  'equals': 'isEqual',
+	  'identical': 'eq',
+	  'init': 'initial',
+	  'invertObj': 'invert',
+	  'juxt': 'over',
+	  'omitAll': 'omit',
+	  'nAry': 'ary',
+	  'path': 'get',
+	  'pathEq': 'matchesProperty',
+	  'pathOr': 'getOr',
+	  'paths': 'at',
+	  'pickAll': 'pick',
+	  'pipe': 'flow',
+	  'pluck': 'map',
+	  'prop': 'get',
+	  'propEq': 'matchesProperty',
+	  'propOr': 'getOr',
+	  'props': 'at',
+	  'unapply': 'rest',
+	  'unnest': 'flatten',
+	  'useWith': 'overArgs',
+	  'whereEq': 'filter',
+	  'zipObj': 'zipObject'
+	};
+
+	/** Used to map ary to method names. */
+	exports.aryMethod = {
+	  '1': [
+	    'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor',
+	    'flow', 'flowRight', 'fromPairs', 'invert', 'iteratee', 'memoize', 'method',
+	    'methodOf', 'mixin', 'over', 'overEvery', 'overSome', 'rest', 'reverse',
+	    'round', 'runInContext', 'spread', 'template', 'trim', 'trimEnd', 'trimStart',
+	    'uniqueId', 'words'
+	  ],
+	  '2': [
+	    'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindAll',
+	    'bindKey', 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
+	    'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
+	    'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith',
+	    'eq', 'every', 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast',
+	    'findLastIndex', 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth',
+	    'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight',
+	    'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf',
+	    'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch',
+	    'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues',
+	    'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'nth',
+	    'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
+	    'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
+	    'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
+	    'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
+	    'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
+	    'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight',
+	    'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars',
+	    'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith',
+	    'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject',
+	    'zipObjectDeep'
+	  ],
+	  '3': [
+	    'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
+	    'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'invokeArgs',
+	    'invokeArgsMap', 'isEqualWith', 'isMatchWith', 'flatMapDepth', 'mergeWith',
+	    'orderBy', 'padChars', 'padCharsEnd', 'padCharsStart', 'pullAllBy',
+	    'pullAllWith', 'reduce', 'reduceRight', 'replace', 'set', 'slice',
+	    'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', 'unionWith',
+	    'update', 'xorBy', 'xorWith', 'zipWith'
+	  ],
+	  '4': [
+	    'fill', 'setWith', 'updateWith'
+	  ]
+	};
+
+	/** Used to map ary to rearg configs. */
+	exports.aryRearg = {
+	  '2': [1, 0],
+	  '3': [2, 0, 1],
+	  '4': [3, 2, 0, 1]
+	};
+
+	/** Used to map method names to their iteratee ary. */
+	exports.iterateeAry = {
+	  'dropRightWhile': 1,
+	  'dropWhile': 1,
+	  'every': 1,
+	  'filter': 1,
+	  'find': 1,
+	  'findIndex': 1,
+	  'findKey': 1,
+	  'findLast': 1,
+	  'findLastIndex': 1,
+	  'findLastKey': 1,
+	  'flatMap': 1,
+	  'flatMapDeep': 1,
+	  'flatMapDepth': 1,
+	  'forEach': 1,
+	  'forEachRight': 1,
+	  'forIn': 1,
+	  'forInRight': 1,
+	  'forOwn': 1,
+	  'forOwnRight': 1,
+	  'map': 1,
+	  'mapKeys': 1,
+	  'mapValues': 1,
+	  'partition': 1,
+	  'reduce': 2,
+	  'reduceRight': 2,
+	  'reject': 1,
+	  'remove': 1,
+	  'some': 1,
+	  'takeRightWhile': 1,
+	  'takeWhile': 1,
+	  'times': 1,
+	  'transform': 2
+	};
+
+	/** Used to map method names to iteratee rearg configs. */
+	exports.iterateeRearg = {
+	  'mapKeys': [1]
+	};
+
+	/** Used to map method names to rearg configs. */
+	exports.methodRearg = {
+	  'assignInWith': [1, 2, 0],
+	  'assignWith': [1, 2, 0],
+	  'getOr': [2, 1, 0],
+	  'isEqualWith': [1, 2, 0],
+	  'isMatchWith': [2, 1, 0],
+	  'mergeWith': [1, 2, 0],
+	  'padChars': [2, 1, 0],
+	  'padCharsEnd': [2, 1, 0],
+	  'padCharsStart': [2, 1, 0],
+	  'pullAllBy': [2, 1, 0],
+	  'pullAllWith': [2, 1, 0],
+	  'setWith': [3, 1, 2, 0],
+	  'sortedIndexBy': [2, 1, 0],
+	  'sortedLastIndexBy': [2, 1, 0],
+	  'updateWith': [3, 1, 2, 0],
+	  'zipWith': [1, 2, 0]
+	};
+
+	/** Used to map method names to spread configs. */
+	exports.methodSpread = {
+	  'invokeArgs': 2,
+	  'invokeArgsMap': 2,
+	  'partial': 1,
+	  'partialRight': 1,
+	  'without': 1
+	};
+
+	/** Used to identify methods which mutate arrays or objects. */
+	exports.mutate = {
+	  'array': {
+	    'fill': true,
+	    'pull': true,
+	    'pullAll': true,
+	    'pullAllBy': true,
+	    'pullAllWith': true,
+	    'pullAt': true,
+	    'remove': true,
+	    'reverse': true
+	  },
+	  'object': {
+	    'assign': true,
+	    'assignIn': true,
+	    'assignInWith': true,
+	    'assignWith': true,
+	    'defaults': true,
+	    'defaultsDeep': true,
+	    'merge': true,
+	    'mergeWith': true
+	  },
+	  'set': {
+	    'set': true,
+	    'setWith': true,
+	    'unset': true,
+	    'update': true,
+	    'updateWith': true
+	  }
+	};
+
+	/** Used to track methods with placeholder support */
+	exports.placeholder = {
+	  'bind': true,
+	  'bindKey': true,
+	  'curry': true,
+	  'curryRight': true,
+	  'partial': true,
+	  'partialRight': true
+	};
+
+	/** Used to map real names to their aliases. */
+	exports.realToAlias = (function() {
+	  var hasOwnProperty = Object.prototype.hasOwnProperty,
+	      object = exports.aliasToReal,
+	      result = {};
+
+	  for (var key in object) {
+	    var value = object[key];
+	    if (hasOwnProperty.call(result, value)) {
+	      result[value].push(key);
+	    } else {
+	      result[value] = [key];
+	    }
+	  }
+	  return result;
+	}());
+
+	/** Used to map method names to other names. */
+	exports.remap = {
+	  'curryN': 'curry',
+	  'curryRightN': 'curryRight',
+	  'getOr': 'get',
+	  'invokeArgs': 'invoke',
+	  'invokeArgsMap': 'invokeMap',
+	  'padChars': 'pad',
+	  'padCharsEnd': 'padEnd',
+	  'padCharsStart': 'padStart',
+	  'restFrom': 'rest',
+	  'spreadFrom': 'spread',
+	  'trimChars': 'trim',
+	  'trimCharsEnd': 'trimEnd',
+	  'trimCharsStart': 'trimStart'
+	};
+
+	/** Used to track methods that skip fixing their arity. */
+	exports.skipFixed = {
+	  'castArray': true,
+	  'flow': true,
+	  'flowRight': true,
+	  'iteratee': true,
+	  'mixin': true,
+	  'runInContext': true
+	};
+
+	/** Used to track methods that skip rearranging arguments. */
+	exports.skipRearg = {
+	  'add': true,
+	  'assign': true,
+	  'assignIn': true,
+	  'bind': true,
+	  'bindKey': true,
+	  'concat': true,
+	  'difference': true,
+	  'divide': true,
+	  'eq': true,
+	  'gt': true,
+	  'gte': true,
+	  'isEqual': true,
+	  'lt': true,
+	  'lte': true,
+	  'matchesProperty': true,
+	  'merge': true,
+	  'multiply': true,
+	  'overArgs': true,
+	  'partial': true,
+	  'partialRight': true,
+	  'random': true,
+	  'range': true,
+	  'rangeRight': true,
+	  'subtract': true,
+	  'without': true,
+	  'zip': true,
+	  'zipObject': true
+	};
+
+
+/***/ },
+/* 3 */
+/***/ function(module, exports) {
+
+	/**
+	 * The default argument placeholder value for methods.
+	 *
+	 * @type {Object}
+	 */
+	module.exports = {};
+
+
+/***/ }
+/******/ ])
+});
+;
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.fp.min.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.fp.min.js
new file mode 100644
index 0000000..bd12b9e
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.fp.min.js
@@ -0,0 +1,16 @@
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.fp=e():t.fp=e()}(this,function(){return function(t){function e(n){if(r[n])return r[n].exports;var i=r[n]={exports:{},id:n,loaded:!1};return t[n].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){function n(t,e){return i(t,t,e)}var i=r(1);"function"==typeof _&&(_=n(_.runInContext())),
+t.exports=n},function(t,e,r){function n(t,e){return 2==e?function(e,r){return t.apply(void 0,arguments)}:function(e){return t.apply(void 0,arguments)}}function i(t,e){return 2==e?function(e,r){return t(e,r)}:function(e){return t(e)}}function a(t){for(var e=t?t.length:0,r=Array(e);e--;)r[e]=t[e];return r}function o(t){return function(e){return t({},e)}}function s(t,e){return function(){var r=arguments.length;if(!r)return i;for(var n=Array(r);r--;)n[r]=arguments[r];var i=n[0]=e.apply(void 0,n);return t.apply(void 0,n),
+i}}function u(t,e,r,d){function f(t,e){e=F(e);for(var r=-1,n=e.length,i=M(Object(t)),a=i;null!=a&&++r<n;){var o=e[r],s=a[o];null!=s&&(a[o]=M(Object(s))),a=a[o]}return i}function h(t){return N.runInContext.convert(t)(void 0)}function y(t,e){var r=d;return function(n){var i=R?B:j,a=R?B[t]:e,o=w(w({},r),n);return u(i,t,a,o)}}function g(t,e){return v(t,function(t){return"function"==typeof t?i(t,e):t})}function m(t,e){return v(t,function(t){var r=e.length;return n(L(i(t,r),e),r)})}function v(t,e){return function(){
+var r=arguments.length;if(!r)return t();for(var n=Array(r);r--;)n[r]=arguments[r];var i=I.rearg?0:r-1;return n[i]=e(n[i]),t.apply(void 0,n)}}function x(t,e){t=p.aliasToReal[t]||t;var r,n=e,i=_[t];return i?n=i(e):I.immutable&&(l.array[t]?n=s(e,a):l.object[t]?n=s(e,o(e)):l.set[t]&&(n=s(e,f))),P(T,function(e){return P(p.aryMethod[e],function(i){if(t==i){var a=!R&&p.iterateeAry[t],o=p.iterateeRearg[t],s=p.methodSpread[t];return r=n,!I.fixed||!k&&p.skipFixed[t]||(r=void 0===s?C(r,e):D(r,s)),I.rearg&&e>1&&(E||!p.skipRearg[t])&&(r=L(r,p.methodRearg[t]||p.aryRearg[e])),
+I.cap&&(o?r=m(r,o):a&&(r=g(r,a))),(b||I.curry&&e>1)&&(b&&console.log(b,t),r=q(r,e)),!1}}),!r}),r||(r=n),r==e&&(r=b?q(r,1):function(){return e.apply(this,arguments)}),r.convert=y(t,e),p.placeholder[t]&&(W=!0,r.placeholder=e.placeholder=O),r}var W,R="function"==typeof e,A=e===Object(e);if(A&&(d=r,r=e,e=void 0),null==r)throw new TypeError;d||(d={});var I={cap:"cap"in d?d.cap:!0,curry:"curry"in d?d.curry:!0,fixed:"fixed"in d?d.fixed:!0,immutable:"immutable"in d?d.immutable:!0,rearg:"rearg"in d?d.rearg:!0
+},b="curry"in d&&d.curry,k="fixed"in d&&d.fixed,E="rearg"in d&&d.rearg,O=R?r:c,B=R?r.runInContext():void 0,j=R?r:{ary:t.ary,assign:t.assign,clone:t.clone,curry:t.curry,forEach:t.forEach,isArray:t.isArray,isFunction:t.isFunction,iteratee:t.iteratee,keys:t.keys,rearg:t.rearg,spread:t.spread,toPath:t.toPath},C=j.ary,w=j.assign,M=j.clone,q=j.curry,P=j.forEach,S=j.isArray,z=j.isFunction,K=j.keys,L=j.rearg,D=j.spread,F=j.toPath,T=K(p.aryMethod),_={castArray:function(t){return function(){var e=arguments[0];
+return S(e)?t(a(e)):t.apply(void 0,arguments)}},iteratee:function(t){return function(){var e=arguments[0],r=arguments[1],n=t(e,r),a=n.length;return I.cap&&"number"==typeof r?(r=r>2?r-2:1,a&&r>=a?n:i(n,r)):n}},mixin:function(t){return function(e){var r=this;if(!z(r))return t(r,Object(e));var n=[],i=[];return P(K(e),function(t){var a=e[t];z(a)&&(i.push(t),n.push(r.prototype[t]))}),t(r,Object(e)),P(i,function(t,e){var i=n[e];z(i)?r.prototype[t]=i:delete r.prototype[t]}),r}},runInContext:function(e){
+return function(r){return u(t,e(r),d)}}};if(!A)return x(e,r);var N=r,V=[];return P(T,function(t){P(p.aryMethod[t],function(t){var e=N[p.remap[t]||t];e&&V.push([t,x(t,e)])})}),P(K(N),function(t){var e=N[t];if("function"==typeof e){for(var r=V.length;r--;)if(V[r][0]==t)return;e.convert=y(t,e),V.push([t,e])}}),P(V,function(t){N[t[0]]=t[1]}),N.convert=h,W&&(N.placeholder=O),P(K(N),function(t){P(p.realToAlias[t]||[],function(e){N[e]=N[t]})}),N}var p=r(2),l=p.mutate,c=r(3);t.exports=u},function(t,e){e.aliasToReal={
+each:"forEach",eachRight:"forEachRight",entries:"toPairs",entriesIn:"toPairsIn",extend:"assignIn",extendWith:"assignInWith",first:"head",__:"placeholder",all:"every",allPass:"overEvery",always:"constant",any:"some",anyPass:"overSome",apply:"spread",assoc:"set",assocPath:"set",complement:"negate",compose:"flowRight",contains:"includes",dissoc:"unset",dissocPath:"unset",equals:"isEqual",identical:"eq",init:"initial",invertObj:"invert",juxt:"over",omitAll:"omit",nAry:"ary",path:"get",pathEq:"matchesProperty",
+pathOr:"getOr",paths:"at",pickAll:"pick",pipe:"flow",pluck:"map",prop:"get",propEq:"matchesProperty",propOr:"getOr",props:"at",unapply:"rest",unnest:"flatten",useWith:"overArgs",whereEq:"filter",zipObj:"zipObject"},e.aryMethod={1:["attempt","castArray","ceil","create","curry","curryRight","floor","flow","flowRight","fromPairs","invert","iteratee","memoize","method","methodOf","mixin","over","overEvery","overSome","rest","reverse","round","runInContext","spread","template","trim","trimEnd","trimStart","uniqueId","words"],
+2:["add","after","ary","assign","assignIn","at","before","bind","bindAll","bindKey","chunk","cloneDeepWith","cloneWith","concat","countBy","curryN","curryRightN","debounce","defaults","defaultsDeep","delay","difference","divide","drop","dropRight","dropRightWhile","dropWhile","endsWith","eq","every","filter","find","find","findIndex","findKey","findLast","findLastIndex","findLastKey","flatMap","flatMapDeep","flattenDepth","forEach","forEachRight","forIn","forInRight","forOwn","forOwnRight","get","groupBy","gt","gte","has","hasIn","includes","indexOf","intersection","invertBy","invoke","invokeMap","isEqual","isMatch","join","keyBy","lastIndexOf","lt","lte","map","mapKeys","mapValues","matchesProperty","maxBy","meanBy","merge","minBy","multiply","nth","omit","omitBy","overArgs","pad","padEnd","padStart","parseInt","partial","partialRight","partition","pick","pickBy","pull","pullAll","pullAt","random","range","rangeRight","rearg","reject","remove","repeat","restFrom","result","sampleSize","some","sortBy","sortedIndex","sortedIndexOf","sortedLastIndex","sortedLastIndexOf","sortedUniqBy","split","spreadFrom","startsWith","subtract","sumBy","take","takeRight","takeRightWhile","takeWhile","tap","throttle","thru","times","trimChars","trimCharsEnd","trimCharsStart","truncate","union","uniqBy","uniqWith","unset","unzipWith","without","wrap","xor","zip","zipObject","zipObjectDeep"],
+3:["assignInWith","assignWith","clamp","differenceBy","differenceWith","getOr","inRange","intersectionBy","intersectionWith","invokeArgs","invokeArgsMap","isEqualWith","isMatchWith","flatMapDepth","mergeWith","orderBy","padChars","padCharsEnd","padCharsStart","pullAllBy","pullAllWith","reduce","reduceRight","replace","set","slice","sortedIndexBy","sortedLastIndexBy","transform","unionBy","unionWith","update","xorBy","xorWith","zipWith"],4:["fill","setWith","updateWith"]},e.aryRearg={2:[1,0],3:[2,0,1],
+4:[3,2,0,1]},e.iterateeAry={dropRightWhile:1,dropWhile:1,every:1,filter:1,find:1,findIndex:1,findKey:1,findLast:1,findLastIndex:1,findLastKey:1,flatMap:1,flatMapDeep:1,flatMapDepth:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},e.iterateeRearg={mapKeys:[1]},e.methodRearg={assignInWith:[1,2,0],assignWith:[1,2,0],getOr:[2,1,0],isEqualWith:[1,2,0],
+isMatchWith:[2,1,0],mergeWith:[1,2,0],padChars:[2,1,0],padCharsEnd:[2,1,0],padCharsStart:[2,1,0],pullAllBy:[2,1,0],pullAllWith:[2,1,0],setWith:[3,1,2,0],sortedIndexBy:[2,1,0],sortedLastIndexBy:[2,1,0],updateWith:[3,1,2,0],zipWith:[1,2,0]},e.methodSpread={invokeArgs:2,invokeArgsMap:2,partial:1,partialRight:1,without:1},e.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAllWith:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignIn:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsDeep:!0,
+merge:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0,update:!0,updateWith:!0}},e.placeholder={bind:!0,bindKey:!0,curry:!0,curryRight:!0,partial:!0,partialRight:!0},e.realToAlias=function(){var t=Object.prototype.hasOwnProperty,r=e.aliasToReal,n={};for(var i in r){var a=r[i];t.call(n,a)?n[a].push(i):n[a]=[i]}return n}(),e.remap={curryN:"curry",curryRightN:"curryRight",getOr:"get",invokeArgs:"invoke",invokeArgsMap:"invokeMap",padChars:"pad",padCharsEnd:"padEnd",padCharsStart:"padStart",restFrom:"rest",
+spreadFrom:"spread",trimChars:"trim",trimCharsEnd:"trimEnd",trimCharsStart:"trimStart"},e.skipFixed={castArray:!0,flow:!0,flowRight:!0,iteratee:!0,mixin:!0,runInContext:!0},e.skipRearg={add:!0,assign:!0,assignIn:!0,bind:!0,bindKey:!0,concat:!0,difference:!0,divide:!0,eq:!0,gt:!0,gte:!0,isEqual:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,multiply:!0,overArgs:!0,partial:!0,partialRight:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,without:!0,zip:!0,zipObject:!0}},function(t,e){t.exports={}}])});
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.js
new file mode 100644
index 0000000..7bc771f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.js
@@ -0,0 +1,16149 @@
+/**
+ * @license
+ * lodash 4.11.2 (Custom Build) <https://lodash.com/>
+ * Build: `lodash -o ./dist/lodash.js`
+ * Copyright jQuery Foundation and other contributors <https://jquery.org/>
+ * 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.11.2';
+
+  /** Used as the size to enable large array optimizations. */
+  var LARGE_ARRAY_SIZE = 200;
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT = 'Expected a function';
+
+  /** Used to stand-in for `undefined` hash values. */
+  var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+  /** Used as the internal argument placeholder. */
+  var PLACEHOLDER = '__lodash_placeholder__';
+
+  /** Used to compose bitmasks for wrapper metadata. */
+  var BIND_FLAG = 1,
+      BIND_KEY_FLAG = 2,
+      CURRY_BOUND_FLAG = 4,
+      CURRY_FLAG = 8,
+      CURRY_RIGHT_FLAG = 16,
+      PARTIAL_FLAG = 32,
+      PARTIAL_RIGHT_FLAG = 64,
+      ARY_FLAG = 128,
+      REARG_FLAG = 256,
+      FLIP_FLAG = 512;
+
+  /** Used to compose bitmasks for comparison styles. */
+  var UNORDERED_COMPARE_FLAG = 1,
+      PARTIAL_COMPARE_FLAG = 2;
+
+  /** 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 = 150,
+      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;
+
+  /** `Object#toString` result references. */
+  var argsTag = '[object Arguments]',
+      arrayTag = '[object Array]',
+      boolTag = '[object Boolean]',
+      dateTag = '[object Date]',
+      errorTag = '[object Error]',
+      funcTag = '[object Function]',
+      genTag = '[object GeneratorFunction]',
+      mapTag = '[object Map]',
+      numberTag = '[object Number]',
+      objectTag = '[object Object]',
+      promiseTag = '[object Promise]',
+      regexpTag = '[object RegExp]',
+      setTag = '[object Set]',
+      stringTag = '[object String]',
+      symbolTag = '[object Symbol]',
+      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|#96);/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*$/,
+      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
+
+  /**
+   * Used to match `RegExp`
+   * [syntax characters](http://ecma-international.org/ecma-262/6.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 non-compound words composed of alphanumeric characters. */
+  var reBasicWord = /[a-zA-Z0-9]+/g;
+
+  /** Used to match backslashes in property paths. */
+  var reEscapeChar = /\\(\\)?/g;
+
+  /**
+   * Used to match
+   * [ES template delimiters](http://ecma-international.org/ecma-262/6.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 hexadecimal string values. */
+  var reHasHexPrefix = /^0x/i;
+
+  /** 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-1 supplementary letters (excluding mathematical operators). */
+  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/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\\ufe20-\\ufe23',
+      rsComboSymbolsRange = '\\u20d0-\\u20f0',
+      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 = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
+      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 rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
+      rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
+      rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
+      rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
+      reOptMod = rsModifier + '?',
+      rsOptVar = '[' + rsVarRange + ']?',
+      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+      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 reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+
+  /** Used to match complex or compound words. */
+  var reComplexWord = RegExp([
+    rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+    rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
+    rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
+    rsUpper + '+' + rsOptUpperContr,
+    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 reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
+
+  /** Used to detect strings that need a more robust regexp to match words. */
+  var reHasComplexWord = /[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', 'Reflect', '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-1 supplementary letters to basic latin letters. */
+  var deburredLetters = {
+    '\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'
+  };
+
+  /** Used to map characters to HTML entities. */
+  var htmlEscapes = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;',
+    '`': '&#96;'
+  };
+
+  /** Used to map HTML entities to characters. */
+  var htmlUnescapes = {
+    '&amp;': '&',
+    '&lt;': '<',
+    '&gt;': '>',
+    '&quot;': '"',
+    '&#39;': "'",
+    '&#96;': '`'
+  };
+
+  /** Used to determine if values are of the language type `Object`. */
+  var objectTypes = {
+    'function': true,
+    'object': true
+  };
+
+  /** 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 `exports`. */
+  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+    ? exports
+    : undefined;
+
+  /** Detect free variable `module`. */
+  var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+    ? module
+    : undefined;
+
+  /** Detect the popular CommonJS extension `module.exports`. */
+  var moduleExports = (freeModule && freeModule.exports === freeExports)
+    ? freeExports
+    : undefined;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+  /** Detect free variable `self`. */
+  var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+  /** Detect free variable `window`. */
+  var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+  /** Detect `this` as the global object. */
+  var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+  /**
+   * Used as a reference to the global object.
+   *
+   * The `this` value is used if it's the global object to avoid Greasemonkey's
+   * restricted `window` object, otherwise the `window` object is used.
+   */
+  var root = freeGlobal ||
+    ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+      freeSelf || thisGlobal || Function('return this')();
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * 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 doesn't return the map instance 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) {
+    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) {
+    var length = args.length;
+    switch (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.length;
+
+    while (++index < length) {
+      var value = array[index];
+      setter(accumulator, value, iteratee(value), array);
+    }
+    return accumulator;
+  }
+
+  /**
+   * Creates a new array concatenating `array` with `other`.
+   *
+   * @private
+   * @param {Array} array The first array to concatenate.
+   * @param {Array} other The second array to concatenate.
+   * @returns {Array} Returns the new concatenated array.
+   */
+  function arrayConcat(array, other) {
+    var index = -1,
+        length = array.length,
+        othIndex = -1,
+        othLength = other.length,
+        result = Array(length + othLength);
+
+    while (++index < length) {
+      result[index] = array[index];
+    }
+    while (++othIndex < othLength) {
+      result[index++] = other[othIndex];
+    }
+    return result;
+  }
+
+  /**
+   * 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.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.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.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.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 search.
+   * @param {*} target The value to search for.
+   * @returns {boolean} Returns `true` if `target` is found, else `false`.
+   */
+  function arrayIncludes(array, value) {
+    return !!array.length && baseIndexOf(array, value, 0) > -1;
+  }
+
+  /**
+   * This function is like `arrayIncludes` except that it accepts a comparator.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @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.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.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.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.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.length;
+
+    while (++index < length) {
+      if (predicate(array[index], index, array)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * The base implementation of methods like `_.find` and `_.findKey`, without
+   * support for iteratee shorthands, which iterates over `collection` using
+   * `eachFunc`.
+   *
+   * @private
+   * @param {Array|Object} collection The collection to search.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {Function} eachFunc The function to iterate over `collection`.
+   * @param {boolean} [retKey] Specify returning the key of the found element
+   *  instead of the element itself.
+   * @returns {*} Returns the found element or its key, else `undefined`.
+   */
+  function baseFind(collection, predicate, eachFunc, retKey) {
+    var result;
+    eachFunc(collection, function(value, key, collection) {
+      if (predicate(value, key, collection)) {
+        result = retKey ? key : value;
+        return false;
+      }
+    });
+    return result;
+  }
+
+  /**
+   * The base implementation of `_.findIndex` and `_.findLastIndex` without
+   * support for iteratee shorthands.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {boolean} [fromRight] Specify iterating from right to left.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function baseFindIndex(array, predicate, fromRight) {
+    var length = array.length,
+        index = fromRight ? length : -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 search.
+   * @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) {
+    if (value !== value) {
+      return indexOfNaN(array, fromIndex);
+    }
+    var index = fromIndex - 1,
+        length = array.length;
+
+    while (++index < length) {
+      if (array[index] === value) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * This function is like `baseIndexOf` except that it accepts a comparator.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @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 `_.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 ? array.length : 0;
+    return length ? (baseSum(array, iteratee) / length) : NAN;
+  }
+
+  /**
+   * 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 new array of 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 wrapper metadata.
+   *
+   * @private
+   * @param {Function} func The function to cap arguments for.
+   * @returns {Function} Returns the new 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];
+    });
+  }
+
+  /**
+   * 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;
+  }
+
+  /**
+   * Checks if `value` is a global object.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+   */
+  function checkGlobal(value) {
+    return (value && value.Object === Object) ? value : null;
+  }
+
+  /**
+   * 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 supplementary letters to basic latin letters.
+   *
+   * @private
+   * @param {string} letter The matched letter to deburr.
+   * @returns {string} Returns the deburred letter.
+   */
+  function deburrLetter(letter) {
+    return deburredLetters[letter];
+  }
+
+  /**
+   * Used by `_.escape` to convert characters to HTML entities.
+   *
+   * @private
+   * @param {string} chr The matched character to escape.
+   * @returns {string} Returns the escaped character.
+   */
+  function escapeHtmlChar(chr) {
+    return htmlEscapes[chr];
+  }
+
+  /**
+   * 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 index at which the first occurrence of `NaN` is found in `array`.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @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 `NaN`, else `-1`.
+   */
+  function indexOfNaN(array, fromIndex, fromRight) {
+    var length = array.length,
+        index = fromIndex + (fromRight ? 0 : -1);
+
+    while ((fromRight ? index-- : ++index < length)) {
+      var other = array[index];
+      if (other !== other) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Checks if `value` is a host object in IE < 9.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+   */
+  function isHostObject(value) {
+    // Many host objects are `Object` objects that can coerce to strings
+    // despite having improperly defined `toString` methods.
+    var result = false;
+    if (value != null && typeof value.toString != 'function') {
+      try {
+        result = !!(value + '');
+      } catch (e) {}
+    }
+    return result;
+  }
+
+  /**
+   * 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 an array.
+   *
+   * @private
+   * @param {Object} map The map to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function mapToArray(map) {
+    var index = -1,
+        result = Array(map.size);
+
+    map.forEach(function(value, key) {
+      result[++index] = [key, value];
+    });
+    return result;
+  }
+
+  /**
+   * 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.
+   *
+   * @private
+   * @param {Object} set The set to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function setToArray(set) {
+    var index = -1,
+        result = Array(set.size);
+
+    set.forEach(function(value) {
+      result[++index] = value;
+    });
+    return result;
+  }
+
+  /**
+   * Gets the number of symbols in `string`.
+   *
+   * @private
+   * @param {string} string The string to inspect.
+   * @returns {number} Returns the string size.
+   */
+  function stringSize(string) {
+    if (!(string && reHasComplexSymbol.test(string))) {
+      return string.length;
+    }
+    var result = reComplexSymbol.lastIndex = 0;
+    while (reComplexSymbol.test(string)) {
+      result++;
+    }
+    return result;
+  }
+
+  /**
+   * Converts `string` to an array.
+   *
+   * @private
+   * @param {string} string The string to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function stringToArray(string) {
+    return string.match(reComplexSymbol);
+  }
+
+  /**
+   * Used by `_.unescape` to convert HTML entities to characters.
+   *
+   * @private
+   * @param {string} chr The matched character to unescape.
+   * @returns {string} Returns the unescaped character.
+   */
+  function unescapeHtmlChar(chr) {
+    return htmlUnescapes[chr];
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * 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
+   *
+   * // Use `context` to mock `Date#getTime` use in `_.now`.
+   * var mock = _.runInContext({
+   *   'Date': function() {
+   *     return { 'getTime': getTimeMock };
+   *   }
+   * });
+   *
+   * // Create a suped-up `defer` in Node.js.
+   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
+   */
+  function runInContext(context) {
+    context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
+
+    /** Built-in constructor references. */
+    var Date = context.Date,
+        Error = context.Error,
+        Math = context.Math,
+        RegExp = context.RegExp,
+        TypeError = context.TypeError;
+
+    /** Used for built-in method references. */
+    var arrayProto = context.Array.prototype,
+        objectProto = context.Object.prototype,
+        stringProto = context.String.prototype;
+
+    /** Used to resolve the decompiled source of functions. */
+    var funcToString = context.Function.prototype.toString;
+
+    /** Used to check objects for own properties. */
+    var hasOwnProperty = objectProto.hasOwnProperty;
+
+    /** Used to generate unique IDs. */
+    var idCounter = 0;
+
+    /** Used to infer the `Object` constructor. */
+    var objectCtorString = funcToString.call(Object);
+
+    /**
+     * Used to resolve the
+     * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+     * of values.
+     */
+    var objectToString = objectProto.toString;
+
+    /** 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,
+        Reflect = context.Reflect,
+        Symbol = context.Symbol,
+        Uint8Array = context.Uint8Array,
+        clearTimeout = context.clearTimeout,
+        enumerate = Reflect ? Reflect.enumerate : undefined,
+        getOwnPropertySymbols = Object.getOwnPropertySymbols,
+        iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
+        objectCreate = Object.create,
+        propertyIsEnumerable = objectProto.propertyIsEnumerable,
+        setTimeout = context.setTimeout,
+        splice = arrayProto.splice;
+
+    /* Built-in method references for those with the same name as other `lodash` methods. */
+    var nativeCeil = Math.ceil,
+        nativeFloor = Math.floor,
+        nativeGetPrototype = Object.getPrototypeOf,
+        nativeIsFinite = context.isFinite,
+        nativeJoin = arrayProto.join,
+        nativeKeys = Object.keys,
+        nativeMax = Math.max,
+        nativeMin = Math.min,
+        nativeParseInt = context.parseInt,
+        nativeRandom = Math.random,
+        nativeReplace = stringProto.replace,
+        nativeReverse = arrayProto.reverse,
+        nativeSplit = stringProto.split;
+
+    /* 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;
+
+    /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
+    var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
+
+    /** 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 of at least `200` elements
+     * and any 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`, `deburr`, `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`, `subtract`, `sum`, `sumBy`, `template`, `times`, `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 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). 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 || arrLength < LARGE_ARRAY_SIZE ||
+          (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
+     * @returns {Object} Returns the new hash object.
+     */
+    function Hash() {}
+
+    /**
+     * Removes `key` and its value from the hash.
+     *
+     * @private
+     * @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(hash, key) {
+      return hashHas(hash, key) && delete hash[key];
+    }
+
+    /**
+     * Gets the hash value for `key`.
+     *
+     * @private
+     * @param {Object} hash The hash to query.
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function hashGet(hash, key) {
+      if (nativeCreate) {
+        var result = hash[key];
+        return result === HASH_UNDEFINED ? undefined : result;
+      }
+      return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
+    }
+
+    /**
+     * Checks if a hash value for `key` exists.
+     *
+     * @private
+     * @param {Object} hash The hash 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 hashHas(hash, key) {
+      return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
+    }
+
+    /**
+     * Sets the hash `key` to `value`.
+     *
+     * @private
+     * @param {Object} hash The hash to modify.
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     */
+    function hashSet(hash, key, value) {
+      hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+    }
+
+    // Avoid inheriting from `Object.prototype` when possible.
+    Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a map cache object to store key-value pairs.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function MapCache(values) {
+      var index = -1,
+          length = values ? values.length : 0;
+
+      this.clear();
+      while (++index < length) {
+        var entry = values[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the map.
+     *
+     * @private
+     * @name clear
+     * @memberOf MapCache
+     */
+    function mapClear() {
+      this.__data__ = {
+        'hash': new Hash,
+        'map': Map ? new Map : [],
+        '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 mapDelete(key) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
+      }
+      return Map ? data.map['delete'](key) : assocDelete(data.map, key);
+    }
+
+    /**
+     * 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 mapGet(key) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        return hashGet(typeof key == 'string' ? data.string : data.hash, key);
+      }
+      return Map ? data.map.get(key) : assocGet(data.map, 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 mapHas(key) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        return hashHas(typeof key == 'string' ? data.string : data.hash, key);
+      }
+      return Map ? data.map.has(key) : assocHas(data.map, 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 mapSet(key, value) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
+      } else if (Map) {
+        data.map.set(key, value);
+      } else {
+        assocSet(data.map, key, value);
+      }
+      return this;
+    }
+
+    // Add methods to `MapCache`.
+    MapCache.prototype.clear = mapClear;
+    MapCache.prototype['delete'] = mapDelete;
+    MapCache.prototype.get = mapGet;
+    MapCache.prototype.has = mapHas;
+    MapCache.prototype.set = mapSet;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     *
+     * Creates a set cache object to store unique values.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function SetCache(values) {
+      var index = -1,
+          length = values ? values.length : 0;
+
+      this.__data__ = new MapCache;
+      while (++index < length) {
+        this.push(values[index]);
+      }
+    }
+
+    /**
+     * Checks if `value` is in `cache`.
+     *
+     * @private
+     * @param {Object} cache The set cache to search.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns `true` if `value` is found, else `false`.
+     */
+    function cacheHas(cache, value) {
+      var map = cache.__data__;
+      if (isKeyable(value)) {
+        var data = map.__data__,
+            hash = typeof value == 'string' ? data.string : data.hash;
+
+        return hash[value] === HASH_UNDEFINED;
+      }
+      return map.has(value);
+    }
+
+    /**
+     * Adds `value` to the set cache.
+     *
+     * @private
+     * @name push
+     * @memberOf SetCache
+     * @param {*} value The value to cache.
+     */
+    function cachePush(value) {
+      var map = this.__data__;
+      if (isKeyable(value)) {
+        var data = map.__data__,
+            hash = typeof value == 'string' ? data.string : data.hash;
+
+        hash[value] = HASH_UNDEFINED;
+      }
+      else {
+        map.set(value, HASH_UNDEFINED);
+      }
+    }
+
+    // Add methods to `SetCache`.
+    SetCache.prototype.push = cachePush;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a stack cache object to store key-value pairs.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function Stack(values) {
+      var index = -1,
+          length = values ? values.length : 0;
+
+      this.clear();
+      while (++index < length) {
+        var entry = values[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the stack.
+     *
+     * @private
+     * @name clear
+     * @memberOf Stack
+     */
+    function stackClear() {
+      this.__data__ = { 'array': [], 'map': null };
+    }
+
+    /**
+     * 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__,
+          array = data.array;
+
+      return array ? assocDelete(array, key) : data.map['delete'](key);
+    }
+
+    /**
+     * 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) {
+      var data = this.__data__,
+          array = data.array;
+
+      return array ? assocGet(array, key) : data.map.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) {
+      var data = this.__data__,
+          array = data.array;
+
+      return array ? assocHas(array, key) : data.map.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__,
+          array = data.array;
+
+      if (array) {
+        if (array.length < (LARGE_ARRAY_SIZE - 1)) {
+          assocSet(array, key, value);
+        } else {
+          data.array = null;
+          data.map = new MapCache(array);
+        }
+      }
+      var map = data.map;
+      if (map) {
+        map.set(key, value);
+      }
+      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;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Removes `key` and its value from the associative array.
+     *
+     * @private
+     * @param {Array} array The array to modify.
+     * @param {string} key The key of the value to remove.
+     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+     */
+    function assocDelete(array, key) {
+      var index = assocIndexOf(array, key);
+      if (index < 0) {
+        return false;
+      }
+      var lastIndex = array.length - 1;
+      if (index == lastIndex) {
+        array.pop();
+      } else {
+        splice.call(array, index, 1);
+      }
+      return true;
+    }
+
+    /**
+     * Gets the associative array value for `key`.
+     *
+     * @private
+     * @param {Array} array The array to query.
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function assocGet(array, key) {
+      var index = assocIndexOf(array, key);
+      return index < 0 ? undefined : array[index][1];
+    }
+
+    /**
+     * Checks if an associative array value for `key` exists.
+     *
+     * @private
+     * @param {Array} array The array 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 assocHas(array, key) {
+      return assocIndexOf(array, key) > -1;
+    }
+
+    /**
+     * Gets the index at which the `key` is found in `array` of key-value pairs.
+     *
+     * @private
+     * @param {Array} array The array to search.
+     * @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;
+    }
+
+    /**
+     * Sets the associative array `key` to `value`.
+     *
+     * @private
+     * @param {Array} array The array to modify.
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     */
+    function assocSet(array, key, value) {
+      var index = assocIndexOf(array, key);
+      if (index < 0) {
+        array.push([key, value]);
+      } else {
+        array[index][1] = value;
+      }
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Used by `_.defaults` to customize its `_.assignIn` use.
+     *
+     * @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 assignInDefaults(objValue, srcValue, key, object) {
+      if (objValue === undefined ||
+          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+        return srcValue;
+      }
+      return objValue;
+    }
+
+    /**
+     * 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)) ||
+          (typeof key == 'number' && value === undefined && !(key in object))) {
+        object[key] = value;
+      }
+    }
+
+    /**
+     * Assigns `value` to `key` of `object` if the existing value is not equivalent
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.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))) {
+        object[key] = value;
+      }
+    }
+
+    /**
+     * 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 `_.at` without support for individual paths.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {string[]} paths The property paths of elements to pick.
+     * @returns {Array} Returns the new array of picked elements.
+     */
+    function baseAt(object, paths) {
+      var index = -1,
+          isNil = object == null,
+          length = paths.length,
+          result = Array(length);
+
+      while (++index < length) {
+        result[index] = isNil ? undefined : get(object, paths[index]);
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
+     *
+     * @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} [isDeep] Specify a deep clone.
+     * @param {boolean} [isFull] Specify a clone including 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, isDeep, isFull, customizer, key, object, stack) {
+      var result;
+      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)) {
+          if (isHostObject(value)) {
+            return object ? value : {};
+          }
+          result = initCloneObject(isFunc ? {} : value);
+          if (!isDeep) {
+            return 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);
+
+      if (!isArr) {
+        var props = isFull ? getAllKeys(value) : keys(value);
+      }
+      // Recursively populate clone (susceptible to call stack limits).
+      arrayEach(props || value, function(subValue, key) {
+        if (props) {
+          key = subValue;
+          subValue = value[key];
+        }
+        assignValue(result, key, baseClone(subValue, isDeep, isFull, 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 function.
+     */
+    function baseConforms(source) {
+      var props = keys(source),
+          length = props.length;
+
+      return function(object) {
+        if (object == null) {
+          return !length;
+        }
+        var index = length;
+        while (index--) {
+          var key = props[index],
+              predicate = source[key],
+              value = object[key];
+
+          if ((value === undefined &&
+              !(key in Object(object))) || !predicate(value)) {
+            return false;
+          }
+        }
+        return true;
+      };
+    }
+
+    /**
+     * The base implementation of `_.create` without support for assigning
+     * properties to the created object.
+     *
+     * @private
+     * @param {Object} prototype The object to inherit from.
+     * @returns {Object} Returns the new object.
+     */
+    function baseCreate(proto) {
+      return isObject(proto) ? objectCreate(proto) : {};
+    }
+
+    /**
+     * The base implementation of `_.delay` and `_.defer` which accepts an array
+     * of `func` arguments.
+     *
+     * @private
+     * @param {Function} func The function to delay.
+     * @param {number} wait The number of milliseconds to delay invocation.
+     * @param {Object} args The arguments to provide to `func`.
+     * @returns {number} Returns the timer id.
+     */
+    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 ? iteratee(value) : 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 new array of filtered property 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 = isKey(path, object) ? [path] : castPath(path);
+
+      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 `_.gt` which doesn't coerce arguments to numbers.
+     *
+     * @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) {
+      // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
+      // that are composed entirely of index properties, return `false` for
+      // `hasOwnProperty` checks of them.
+      return hasOwnProperty.call(object, key) ||
+        (typeof object == 'object' && key in object && getPrototype(object) === null);
+    }
+
+    /**
+     * 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 key in Object(object);
+    }
+
+    /**
+     * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
+     *
+     * @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) {
+      if (!isKey(path, object)) {
+        path = castPath(path);
+        object = parent(object, path);
+        path = last(path);
+      }
+      var func = object == null ? object : object[toKey(path)];
+      return func == null ? undefined : apply(func, object, args);
+    }
+
+    /**
+     * 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 {Function} [customizer] The function to customize comparisons.
+     * @param {boolean} [bitmask] The bitmask of comparison flags.
+     *  The bitmask may be composed of the following flags:
+     *     1 - Unordered comparison
+     *     2 - Partial comparison
+     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     */
+    function baseIsEqual(value, other, customizer, bitmask, stack) {
+      if (value === other) {
+        return true;
+      }
+      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+        return value !== value && other !== other;
+      }
+      return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, 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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} [customizer] The function to customize comparisons.
+     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
+      var objIsArr = isArray(object),
+          othIsArr = isArray(other),
+          objTag = arrayTag,
+          othTag = arrayTag;
+
+      if (!objIsArr) {
+        objTag = getTag(object);
+        objTag = objTag == argsTag ? objectTag : objTag;
+      }
+      if (!othIsArr) {
+        othTag = getTag(other);
+        othTag = othTag == argsTag ? objectTag : othTag;
+      }
+      var objIsObj = objTag == objectTag && !isHostObject(object),
+          othIsObj = othTag == objectTag && !isHostObject(other),
+          isSameTag = objTag == othTag;
+
+      if (isSameTag && !objIsObj) {
+        stack || (stack = new Stack);
+        return (objIsArr || isTypedArray(object))
+          ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
+          : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
+      }
+      if (!(bitmask & PARTIAL_COMPARE_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, customizer, bitmask, stack);
+        }
+      }
+      if (!isSameTag) {
+        return false;
+      }
+      stack || (stack = new Stack);
+      return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
+    }
+
+    /**
+     * 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, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
+                : result
+              )) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+
+    /**
+     * 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 skip the constructor
+     * property of prototypes or treat sparse arrays as dense.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function baseKeys(object) {
+      return nativeKeys(Object(object));
+    }
+
+    /**
+     * The base implementation of `_.keysIn` which doesn't skip the constructor
+     * property of prototypes or treat sparse arrays as dense.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function baseKeysIn(object) {
+      object = object == null ? object : Object(object);
+
+      var result = [];
+      for (var key in object) {
+        result.push(key);
+      }
+      return result;
+    }
+
+    // Fallback for IE < 9 with es6-shim.
+    if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
+      baseKeysIn = function(object) {
+        return iteratorToArray(enumerate(object));
+      };
+    }
+
+    /**
+     * The base implementation of `_.lt` which doesn't coerce arguments to numbers.
+     *
+     * @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 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 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, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_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;
+      }
+      if (!(isArray(source) || isTypedArray(source))) {
+        var props = keysIn(source);
+      }
+      arrayEach(props || source, function(srcValue, key) {
+        if (props) {
+          key = srcValue;
+          srcValue = source[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);
+        }
+      });
+    }
+
+    /**
+     * 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) {
+        newValue = srcValue;
+        if (isArray(srcValue) || isTypedArray(srcValue)) {
+          if (isArray(objValue)) {
+            newValue = objValue;
+          }
+          else if (isArrayLikeObject(objValue)) {
+            newValue = copyArray(objValue);
+          }
+          else {
+            isCommon = false;
+            newValue = baseClone(srcValue, true);
+          }
+        }
+        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+          if (isArguments(objValue)) {
+            newValue = toPlainObject(objValue);
+          }
+          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
+            isCommon = false;
+            newValue = baseClone(srcValue, true);
+          }
+          else {
+            newValue = objValue;
+          }
+        }
+        else {
+          isCommon = false;
+        }
+      }
+      stack.set(srcValue, newValue);
+
+      if (isCommon) {
+        // Recursively merge objects and arrays (susceptible to call stack limits).
+        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
+      }
+      stack['delete'](srcValue);
+      assignMergeValue(object, key, newValue);
+    }
+
+    /**
+     * The base implementation of `_.nth` which doesn't coerce `n` to an integer.
+     *
+     * @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[]} props The property identifiers to pick.
+     * @returns {Object} Returns the new object.
+     */
+    function basePick(object, props) {
+      object = Object(object);
+      return arrayReduce(props, function(result, key) {
+        if (key in object) {
+          result[key] = object[key];
+        }
+        return result;
+      }, {});
+    }
+
+    /**
+     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Object} object The source object.
+     * @param {Function} predicate The function invoked per property.
+     * @returns {Object} Returns the new object.
+     */
+    function basePickBy(object, predicate) {
+      var index = -1,
+          props = getAllKeysIn(object),
+          length = props.length,
+          result = {};
+
+      while (++index < length) {
+        var key = props[index],
+            value = object[key];
+
+        if (predicate(value, key)) {
+          result[key] = value;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * 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 function.
+     */
+    function baseProperty(key) {
+      return function(object) {
+        return object == null ? undefined : object[key];
+      };
+    }
+
+    /**
+     * 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 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 (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 if (!isKey(index, array)) {
+            var path = castPath(index),
+                object = parent(array, path);
+
+            if (object != null) {
+              delete object[toKey(last(path))];
+            }
+          }
+          else {
+            delete array[toKey(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 to numbers.
+     *
+     * @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 new array 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 `_.set`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @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) {
+      path = isKey(path, object) ? [path] : castPath(path);
+
+      var index = -1,
+          length = path.length,
+          lastIndex = length - 1,
+          nested = object;
+
+      while (nested != null && ++index < length) {
+        var key = toKey(path[index]);
+        if (isObject(nested)) {
+          var newValue = value;
+          if (index != lastIndex) {
+            var objValue = nested[key];
+            newValue = customizer ? customizer(objValue, key, nested) : undefined;
+            if (newValue === undefined) {
+              newValue = objValue == null
+                ? (isIndex(path[index + 1]) ? [] : {})
+                : objValue;
+            }
+          }
+          assignValue(nested, key, newValue);
+        }
+        nested = nested[key];
+      }
+      return object;
+    }
+
+    /**
+     * The base implementation of `setData` without support for hot loop detection.
+     *
+     * @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 `_.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 ? array.length : low;
+
+      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 ? array.length : 0,
+          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 (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 path of the property to unset.
+     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+     */
+    function baseUnset(object, path) {
+      path = isKey(path, object) ? [path] : castPath(path);
+      object = parent(object, path);
+
+      var key = toKey(last(path));
+      return !(object != null && baseHas(object, key)) || delete object[key];
+    }
+
+    /**
+     * The base implementation of `_.update`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @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 index = -1,
+          length = arrays.length;
+
+      while (++index < length) {
+        var result = result
+          ? arrayPush(
+              baseDifference(result, arrays[index], iteratee, comparator),
+              baseDifference(arrays[index], result, iteratee, comparator)
+            )
+          : arrays[index];
+      }
+      return (result && result.length) ? baseUniq(result, 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.
+     * @returns {Array} Returns the cast property path array.
+     */
+    function castPath(value) {
+      return isArray(value) ? value : stringToPath(value);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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 result = new buffer.constructor(buffer.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), true) : 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), true) : 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|Object} 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|Object} 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) {
+      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)
+          : source[key];
+
+        assignValue(object, key, newValue);
+      }
+      return object;
+    }
+
+    /**
+     * Copies own symbol properties 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);
+    }
+
+    /**
+     * 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), 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 rest(function(object, sources) {
+        var index = -1,
+            length = sources.length,
+            customizer = length > 1 ? sources[length - 1] : undefined,
+            guard = length > 2 ? sources[2] : undefined;
+
+        customizer = 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 of wrapper flags. See `createWrapper`
+     *  for more details.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createBaseWrapper(func, bitmask, thisArg) {
+      var isBind = bitmask & BIND_FLAG,
+          Ctor = createCtorWrapper(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 function.
+     */
+    function createCaseFirst(methodName) {
+      return function(string) {
+        string = toString(string);
+
+        var strSymbols = reHasComplexSymbol.test(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 createCtorWrapper(Ctor) {
+      return function() {
+        // Use a `switch` statement to work with class constructors. See
+        // http://ecma-international.org/ecma-262/6.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 of wrapper flags. See `createWrapper`
+     *  for more details.
+     * @param {number} arity The arity of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createCurryWrapper(func, bitmask, arity) {
+      var Ctor = createCtorWrapper(func);
+
+      function wrapper() {
+        var length = arguments.length,
+            args = Array(length),
+            index = length,
+            placeholder = getPlaceholder(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 createRecurryWrapper(
+            func, bitmask, createHybridWrapper, 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 `_.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 rest(function(funcs) {
+        funcs = baseFlatten(funcs, 1);
+
+        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] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | 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) && value.length >= LARGE_ARRAY_SIZE) {
+            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 of wrapper flags. See `createWrapper`
+     *  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 createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+      var isAry = bitmask & ARY_FLAG,
+          isBind = bitmask & BIND_FLAG,
+          isBindKey = bitmask & BIND_KEY_FLAG,
+          isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
+          isFlip = bitmask & FLIP_FLAG,
+          Ctor = isBindKey ? undefined : createCtorWrapper(func);
+
+      function wrapper() {
+        var length = arguments.length,
+            index = length,
+            args = Array(length);
+
+        while (index--) {
+          args[index] = arguments[index];
+        }
+        if (isCurried) {
+          var placeholder = getPlaceholder(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 createRecurryWrapper(
+            func, bitmask, createHybridWrapper, 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 || createCtorWrapper(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.
+     * @returns {Function} Returns the new mathematical operation function.
+     */
+    function createMathOperation(operator) {
+      return function(value, other) {
+        var result;
+        if (value === undefined && other === undefined) {
+          return 0;
+        }
+        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 invoker function.
+     */
+    function createOver(arrayFunc) {
+      return rest(function(iteratees) {
+        iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
+          ? arrayMap(iteratees[0], baseUnary(getIteratee()))
+          : arrayMap(baseFlatten(iteratees, 1, isFlattenableIteratee), baseUnary(getIteratee()));
+
+        return rest(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 reHasComplexSymbol.test(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 of wrapper flags. See `createWrapper`
+     *  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 createPartialWrapper(func, bitmask, thisArg, partials) {
+      var isBind = bitmask & BIND_FLAG,
+          Ctor = createCtorWrapper(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 = toNumber(start);
+        start = start === start ? start : 0;
+        if (end === undefined) {
+          end = start;
+          start = 0;
+        } else {
+          end = toNumber(end) || 0;
+        }
+        step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
+        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 of wrapper flags. See `createWrapper`
+     *  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 createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
+      var isCurry = bitmask & CURRY_FLAG,
+          newHolders = isCurry ? holders : undefined,
+          newHoldersRight = isCurry ? undefined : holders,
+          newPartials = isCurry ? partials : undefined,
+          newPartialsRight = isCurry ? undefined : partials;
+
+      bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+      bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+      if (!(bitmask & CURRY_BOUND_FLAG)) {
+        bitmask &= ~(BIND_FLAG | 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 result;
+    }
+
+    /**
+     * 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 = toInteger(precision);
+        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 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 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 of wrapper flags.
+     *  The bitmask may be composed of the following 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`
+     * @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 createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+      var isBindKey = bitmask & BIND_KEY_FLAG;
+      if (!isBindKey && typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      var length = partials ? partials.length : 0;
+      if (!length) {
+        bitmask &= ~(PARTIAL_FLAG | 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 & 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] == null
+        ? (isBindKey ? 0 : func.length)
+        : nativeMax(newData[9] - length, 0);
+
+      if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
+        bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
+      }
+      if (!bitmask || bitmask == BIND_FLAG) {
+        var result = createBaseWrapper(func, bitmask, thisArg);
+      } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
+        result = createCurryWrapper(func, bitmask, arity);
+      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
+        result = createPartialWrapper(func, bitmask, thisArg, partials);
+      } else {
+        result = createHybridWrapper.apply(undefined, newData);
+      }
+      var setter = data ? baseSetData : setData;
+      return setter(result, newData);
+    }
+
+    /**
+     * 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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @param {Object} stack Tracks traversed `array` and `other` objects.
+     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+     */
+    function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
+      var index = -1,
+          isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+          isUnordered = bitmask & UNORDERED_COMPARE_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) {
+        return stacked == other;
+      }
+      var result = true;
+      stack.set(array, other);
+
+      // 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 (isUnordered) {
+          if (!arraySome(other, function(othValue) {
+                return arrValue === othValue ||
+                  equalFunc(arrValue, othValue, customizer, bitmask, stack);
+              })) {
+            result = false;
+            break;
+          }
+        } else if (!(
+              arrValue === othValue ||
+                equalFunc(arrValue, othValue, customizer, bitmask, stack)
+            )) {
+          result = false;
+          break;
+        }
+      }
+      stack['delete'](array);
+      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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @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, equalFunc, customizer, bitmask, 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:
+          // Coerce dates and booleans to numbers, dates to milliseconds and
+          // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
+          // not equal.
+          return +object == +other;
+
+        case errorTag:
+          return object.name == other.name && object.message == other.message;
+
+        case numberTag:
+          // Treat `NaN` vs. `NaN` as equal.
+          return (object != +object) ? other != +other : object == +other;
+
+        case regexpTag:
+        case stringTag:
+          // Coerce regexes to strings and treat strings, primitives and objects,
+          // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
+          // for more details.
+          return object == (other + '');
+
+        case mapTag:
+          var convert = mapToArray;
+
+        case setTag:
+          var isPartial = bitmask & PARTIAL_COMPARE_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 |= UNORDERED_COMPARE_FLAG;
+          stack.set(object, other);
+
+          // Recursively compare objects (susceptible to call stack limits).
+          return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
+
+        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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @param {Object} stack Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
+      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+          objProps = keys(object),
+          objLength = objProps.length,
+          othProps = keys(other),
+          othLength = othProps.length;
+
+      if (objLength != othLength && !isPartial) {
+        return false;
+      }
+      var index = objLength;
+      while (index--) {
+        var key = objProps[index];
+        if (!(isPartial ? key in other : baseHas(other, key))) {
+          return false;
+        }
+      }
+      // Assume cyclic values are equal.
+      var stacked = stack.get(object);
+      if (stacked) {
+        return stacked == other;
+      }
+      var result = true;
+      stack.set(object, other);
+
+      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, customizer, bitmask, 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);
+      return result;
+    }
+
+    /**
+     * 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 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 "length" property value of `object`.
+     *
+     * **Note:** This function is used to avoid a
+     * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
+     * Safari on at least iOS 8.1-8.3 ARM64.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {*} Returns the "length" value.
+     */
+    var getLength = baseProperty('length');
+
+    /**
+     * 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 = toPairs(object),
+          length = result.length;
+
+      while (length--) {
+        result[length][2] = isStrictComparable(result[length][1]);
+      }
+      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 = object[key];
+      return isNative(value) ? value : undefined;
+    }
+
+    /**
+     * Gets the argument placeholder value for `func`.
+     *
+     * @private
+     * @param {Function} func The function to inspect.
+     * @returns {*} Returns the placeholder value.
+     */
+    function getPlaceholder(func) {
+      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
+      return object.placeholder;
+    }
+
+    /**
+     * Gets the `[[Prototype]]` of `value`.
+     *
+     * @private
+     * @param {*} value The value to query.
+     * @returns {null|Object} Returns the `[[Prototype]]`.
+     */
+    function getPrototype(value) {
+      return nativeGetPrototype(Object(value));
+    }
+
+    /**
+     * Creates an array of the own enumerable symbol properties of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of symbols.
+     */
+    function getSymbols(object) {
+      // Coerce `object` to an object to avoid non-object errors in V8.
+      // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.
+      return getOwnPropertySymbols(Object(object));
+    }
+
+    // Fallback for IE < 11.
+    if (!getOwnPropertySymbols) {
+      getSymbols = function() {
+        return [];
+      };
+    }
+
+    /**
+     * Creates an array of the own and inherited enumerable symbol properties
+     * of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of symbols.
+     */
+    var getSymbolsIn = !getOwnPropertySymbols ? getSymbols : 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`.
+     */
+    function getTag(value) {
+      return objectToString.call(value);
+    }
+
+    // Fallback for data views, maps, sets, and weak maps in IE 11,
+    // for data views in Edge, and promises in Node.js.
+    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 = objectToString.call(value),
+            Ctor = result == objectTag ? value.constructor : undefined,
+            ctorString = Ctor ? toSource(Ctor) : undefined;
+
+        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 };
+    }
+
+    /**
+     * 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 = isKey(path, object) ? [path] : castPath(path);
+
+      var result,
+          index = -1,
+          length = path.length;
+
+      while (++index < length) {
+        var key = toKey(path[index]);
+        if (!(result = object != null && hasFunc(object, key))) {
+          break;
+        }
+        object = object[key];
+      }
+      if (result) {
+        return result;
+      }
+      var length = object ? object.length : 0;
+      return !!length && isLength(length) && isIndex(key, length) &&
+        (isArray(object) || isString(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);
+      }
+    }
+
+    /**
+     * Creates an array of index keys for `object` values of arrays,
+     * `arguments` objects, and strings, otherwise `null` is returned.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array|null} Returns index keys, else `null`.
+     */
+    function indexKeys(object) {
+      var length = object ? object.length : undefined;
+      if (isLength(length) &&
+          (isArray(object) || isString(object) || isArguments(object))) {
+        return baseTimes(length, String);
+      }
+      return null;
+    }
+
+    /**
+     * 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 isArrayLikeObject(value) && (isArray(value) || isArguments(value));
+    }
+
+    /**
+     * Checks if `value` is a flattenable array and not a `_.matchesProperty`
+     * iteratee shorthand.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+     */
+    function isFlattenableIteratee(value) {
+      return isArray(value) && !(value.length == 2 && !isFunction(value[0]));
+    }
+
+    /**
+     * 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 `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 function.
+     */
+    function matchesStrictComparable(key, srcValue) {
+      return function(object) {
+        if (object == null) {
+          return false;
+        }
+        return object[key] === srcValue &&
+          (srcValue !== undefined || (key in Object(object)));
+      };
+    }
+
+    /**
+     * 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 < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
+
+      var isCombo =
+        ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
+        ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
+        ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
+
+      // Exit early if metadata can't be merged.
+      if (!(isCommon || isCombo)) {
+        return data;
+      }
+      // Use source `thisArg` if available.
+      if (srcBitmask & BIND_FLAG) {
+        data[2] = source[2];
+        // Set when currying a bound function.
+        newBitmask |= bitmask & BIND_FLAG ? 0 : 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 & 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;
+    }
+
+    /**
+     * Used by `_.defaultsDeep` to customize its `_.merge` use.
+     *
+     * @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 mergeDefaults(objValue, srcValue, key, object, source, stack) {
+      if (isObject(objValue) && isObject(srcValue)) {
+        baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue));
+      }
+      return objValue;
+    }
+
+    /**
+     * 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 == 1 ? 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 = (function() {
+      var count = 0,
+          lastCalled = 0;
+
+      return function(key, value) {
+        var stamp = now(),
+            remaining = HOT_SPAN - (stamp - lastCalled);
+
+        lastCalled = stamp;
+        if (remaining > 0) {
+          if (++count >= HOT_COUNT) {
+            return key;
+          }
+        } else {
+          count = 0;
+        }
+        return baseSetData(key, value);
+      };
+    }());
+
+    /**
+     * Converts `string` to a property path array.
+     *
+     * @private
+     * @param {string} string The string to convert.
+     * @returns {Array} Returns the property path array.
+     */
+    var stringToPath = memoize(function(string) {
+      var result = [];
+      toString(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 process.
+     * @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 '';
+    }
+
+    /**
+     * 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 containing 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 ? array.length : 0;
+      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 ? array.length : 0,
+          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,
+          array = castArray(arguments[0]);
+
+      if (length < 2) {
+        return length ? copyArray(array) : [];
+      }
+      var args = Array(length - 1);
+      while (length--) {
+        args[length - 1] = arguments[length];
+      }
+      return arrayConcat(array, baseFlatten(args, 1));
+    }
+
+    /**
+     * Creates an array of unique `array` values not included in the other given
+     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+     * for equality comparisons. The order of result values is determined by the
+     * order they occur in the first 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([3, 2, 1], [4, 2]);
+     * // => [3, 1]
+     */
+    var difference = rest(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. Result values are chosen from the first 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 {...Array} [values] The values to exclude.
+     * @param {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
+     * // => [3.1, 1.3]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+     * // => [{ 'x': 2 }]
+     */
+    var differenceBy = rest(function(array, values) {
+      var iteratee = last(values);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return isArrayLikeObject(array)
+        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee))
+        : [];
+    });
+
+    /**
+     * This method is like `_.difference` except that it accepts `comparator`
+     * which is invoked to compare elements of `array` to `values`. Result values
+     * are chosen from the first 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 {...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 = rest(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 ? array.length : 0;
+      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 ? array.length : 0;
+      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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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 ? array.length : 0;
+      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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @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) {
+      return (array && array.length)
+        ? baseFindIndex(array, getIteratee(predicate, 3))
+        : -1;
+    }
+
+    /**
+     * 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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @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) {
+      return (array && array.length)
+        ? baseFindIndex(array, getIteratee(predicate, 3), true)
+        : -1;
+    }
+
+    /**
+     * 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 ? array.length : 0;
+      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 ? array.length : 0;
+      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 ? array.length : 0;
+      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([['fred', 30], ['barney', 40]]);
+     * // => { 'fred': 30, 'barney': 40 }
+     */
+    function fromPairs(pairs) {
+      var index = -1,
+          length = pairs ? pairs.length : 0,
+          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/6.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 search.
+     * @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 ? array.length : 0;
+      if (!length) {
+        return -1;
+      }
+      fromIndex = toInteger(fromIndex);
+      if (fromIndex < 0) {
+        fromIndex = nativeMax(length + fromIndex, 0);
+      }
+      return baseIndexOf(array, value, fromIndex);
+    }
+
+    /**
+     * 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) {
+      return dropRight(array, 1);
+    }
+
+    /**
+     * Creates an array of unique values that are included in all given arrays
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+     * for equality comparisons. The order of result values is determined by the
+     * order they occur in 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], [4, 2], [1, 2]);
+     * // => [2]
+     */
+    var intersection = rest(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. Result values are chosen from 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 {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of intersecting values.
+     * @example
+     *
+     * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+     * // => [2.1]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }]
+     */
+    var intersectionBy = rest(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))
+        : [];
+    });
+
+    /**
+     * This method is like `_.intersection` except that it accepts `comparator`
+     * which is invoked to compare elements of `arrays`. Result values are chosen
+     * from 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 = rest(function(arrays) {
+      var comparator = last(arrays),
+          mapped = arrayMap(arrays, castArrayLikeObject);
+
+      if (comparator === last(mapped)) {
+        comparator = undefined;
+      } else {
+        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 ? 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 ? array.length : 0;
+      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 search.
+     * @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 ? array.length : 0;
+      if (!length) {
+        return -1;
+      }
+      var index = length;
+      if (fromIndex !== undefined) {
+        index = toInteger(fromIndex);
+        index = (
+          index < 0
+            ? nativeMax(length + index, 0)
+            : nativeMin(index, length - 1)
+        ) + 1;
+      }
+      if (value !== value) {
+        return indexOfNaN(array, index, true);
+      }
+      while (index--) {
+        if (array[index] === value) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * Gets the nth element 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/6.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 = [1, 2, 3, 1, 2, 3];
+     *
+     * _.pull(array, 2, 3);
+     * console.log(array);
+     * // => [1, 1]
+     */
+    var pull = rest(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 = [1, 2, 3, 1, 2, 3];
+     *
+     * _.pullAll(array, [2, 3]);
+     * console.log(array);
+     * // => [1, 1]
+     */
+    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 {Array|Function|Object|string} [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))
+        : 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 = [5, 10, 15, 20];
+     * var evens = _.pullAt(array, 1, 3);
+     *
+     * console.log(array);
+     * // => [5, 15]
+     *
+     * console.log(evens);
+     * // => [10, 20]
+     */
+    var pullAt = rest(function(array, indexes) {
+      indexes = baseFlatten(indexes, 1);
+
+      var length = array ? array.length : 0,
+          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 {Array|Function|Object|string} [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 ? nativeReverse.call(array) : 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 ? array.length : 0;
+      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
+     *
+     * _.sortedIndex([4, 5], 4);
+     * // => 0
+     */
+    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 {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
+     *
+     * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
+     * // => 1
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+     * // => 0
+     */
+    function sortedIndexBy(array, value, iteratee) {
+      return baseSortedIndexBy(array, value, getIteratee(iteratee));
+    }
+
+    /**
+     * 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 search.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.sortedIndexOf([1, 1, 2, 2], 2);
+     * // => 2
+     */
+    function sortedIndexOf(array, value) {
+      var length = array ? array.length : 0;
+      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], 4);
+     * // => 1
+     */
+    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 {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+     * // => 1
+     */
+    function sortedLastIndexBy(array, value, iteratee) {
+      return baseSortedIndexBy(array, value, getIteratee(iteratee), 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 search.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.sortedLastIndexOf([1, 1, 2, 2], 2);
+     * // => 3
+     */
+    function sortedLastIndexOf(array, value) {
+      var length = array ? array.length : 0;
+      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))
+        : [];
+    }
+
+    /**
+     * 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) {
+      return drop(array, 1);
+    }
+
+    /**
+     * 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 ? array.length : 0;
+      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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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/6.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], [4, 2], [1, 2]);
+     * // => [2, 1, 4]
+     */
+    var union = rest(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. The iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of combined values.
+     * @example
+     *
+     * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+     * // => [2.1, 1.2, 4.3]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }, { 'x': 2 }]
+     */
+    var unionBy = rest(function(arrays) {
+      var iteratee = last(arrays);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee));
+    });
+
+    /**
+     * This method is like `_.union` except that it accepts `comparator` which
+     * is invoked to compare elements of `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 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 = rest(function(arrays) {
+      var comparator = last(arrays);
+      if (isArrayLikeObject(comparator)) {
+        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/6.0/#sec-samevaluezero)
+     * for equality comparisons, in which only the first occurrence of each
+     * element is kept.
+     *
+     * @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 iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Array|Function|Object|string} [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))
+        : [];
+    }
+
+    /**
+     * This method is like `_.uniq` except that it accepts `comparator` which
+     * is invoked to compare elements of `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) {
+      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(['fred', 'barney'], [30, 40], [true, false]);
+     * // => [['fred', 30, true], ['barney', 40, false]]
+     *
+     * _.unzip(zipped);
+     * // => [['fred', 'barney'], [30, 40], [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/6.0/#sec-samevaluezero)
+     * for equality comparisons.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to filter.
+     * @param {...*} [values] The values to exclude.
+     * @returns {Array} Returns the new array of filtered values.
+     * @see _.difference, _.xor
+     * @example
+     *
+     * _.without([1, 2, 1, 3], 1, 2);
+     * // => [3]
+     */
+    var without = rest(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 values.
+     * @see _.difference, _.without
+     * @example
+     *
+     * _.xor([2, 1], [4, 2]);
+     * // => [1, 4]
+     */
+    var xor = rest(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 iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of values.
+     * @example
+     *
+     * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+     * // => [1.2, 4.3]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 2 }]
+     */
+    var xorBy = rest(function(arrays) {
+      var iteratee = last(arrays);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
+    });
+
+    /**
+     * This method is like `_.xor` except that it accepts `comparator` which is
+     * invoked to compare elements of `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 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 = rest(function(arrays) {
+      var comparator = last(arrays);
+      if (isArrayLikeObject(comparator)) {
+        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(['fred', 'barney'], [30, 40], [true, false]);
+     * // => [['fred', 30, true], ['barney', 40, false]]
+     */
+    var zip = rest(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 = rest(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 of elements 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]
+     *
+     * _(['a', 'b', 'c']).at(0, 2).value();
+     * // => ['a', 'c']
+     */
+    var wrapperAt = rest(function(paths) {
+      paths = baseFlatten(paths, 1);
+      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 {Array|Function|Object|string} [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 }
+     *
+     * _.countBy(['one', 'two', 'three'], 'length');
+     * // => { '3': 2, '5': 1 }
+     */
+    var countBy = createAggregator(function(result, value, key) {
+      hasOwnProperty.call(result, key) ? ++result[key] : (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).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Array|Function|Object|string} [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).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Array|Function|Object|string} [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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @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'
+     */
+    function find(collection, predicate) {
+      predicate = getIteratee(predicate, 3);
+      if (isArray(collection)) {
+        var index = baseFindIndex(collection, predicate);
+        return index > -1 ? collection[index] : undefined;
+      }
+      return baseFind(collection, predicate, baseEach);
+    }
+
+    /**
+     * 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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @returns {*} Returns the matched element, else `undefined`.
+     * @example
+     *
+     * _.findLast([1, 2, 3, 4], function(n) {
+     *   return n % 2 == 1;
+     * });
+     * // => 3
+     */
+    function findLast(collection, predicate) {
+      predicate = getIteratee(predicate, 3);
+      if (isArray(collection)) {
+        var index = baseFindIndex(collection, predicate, true);
+        return index > -1 ? collection[index] : undefined;
+      }
+      return baseFind(collection, predicate, baseEachRight);
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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
+     *
+     * _([1, 2]).forEach(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) {
+      return (typeof iteratee == 'function' && isArray(collection))
+        ? arrayEach(collection, iteratee)
+        : baseEach(collection, getIteratee(iteratee));
+    }
+
+    /**
+     * 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) {
+      return (typeof iteratee == 'function' && isArray(collection))
+        ? arrayEachRight(collection, iteratee)
+        : baseEachRight(collection, getIteratee(iteratee));
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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 {
+        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/6.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 search.
+     * @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({ 'user': 'fred', 'age': 40 }, 'fred');
+     * // => true
+     *
+     * _.includes('pebbles', 'eb');
+     * // => 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 `methodName` 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 = rest(function(collection, path, args) {
+      var index = -1,
+          isFunc = typeof path == 'function',
+          isProp = isKey(path),
+          result = isArrayLike(collection) ? Array(collection.length) : [];
+
+      baseEach(collection, function(value) {
+        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
+        result[++index] = func ? apply(func, 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 {Array|Function|Object|string} [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) {
+      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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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;
+      predicate = getIteratee(predicate, 3);
+      return func(collection, function(value, index, collection) {
+        return !predicate(value, index, collection);
+      });
+    }
+
+    /**
+     * 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 array = isArrayLike(collection) ? collection : values(collection),
+          length = array.length;
+
+      return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
+    }
+
+    /**
+     * 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) {
+      var index = -1,
+          result = toArray(collection),
+          length = result.length,
+          lastIndex = length - 1;
+
+      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
+        n = 1;
+      } else {
+        n = baseClamp(toInteger(n), 0, length);
+      }
+      while (++index < n) {
+        var rand = baseRandom(index, lastIndex),
+            value = result[rand];
+
+        result[rand] = result[index];
+        result[index] = value;
+      }
+      result.length = n;
+      return result;
+    }
+
+    /**
+     * 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) {
+      return sampleSize(collection, MAX_ARRAY_LENGTH);
+    }
+
+    /**
+     * 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} 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)) {
+        var result = collection.length;
+        return (result && isString(collection)) ? stringSize(collection) : result;
+      }
+      if (isObjectLike(collection)) {
+        var tag = getTag(collection);
+        if (tag == mapTag || tag == setTag) {
+          return collection.size;
+        }
+      }
+      return keys(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 {Array|Function|Object|string} [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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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]]
+     *
+     * _.sortBy(users, 'user', function(o) {
+     *   return Math.floor(o.age / 10);
+     * });
+     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+     */
+    var sortBy = rest(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]];
+      }
+      iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
+        ? iteratees[0]
+        : baseFlatten(iteratees, 1, isFlattenableIteratee);
+
+      return baseOrderBy(collection, iteratees, []);
+    });
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * 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
+     * @type {Function}
+     * @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 function to be invoked.
+     */
+    var now = 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 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 createWrapper(func, 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
+     *
+     * var greet = function(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 = rest(function(func, thisArg, partials) {
+      var bitmask = BIND_FLAG;
+      if (partials.length) {
+        var holders = replaceHolders(partials, getPlaceholder(bind));
+        bitmask |= PARTIAL_FLAG;
+      }
+      return createWrapper(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 = rest(function(object, key, partials) {
+      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
+      if (partials.length) {
+        var holders = replaceHolders(partials, getPlaceholder(bindKey));
+        bitmask |= PARTIAL_FLAG;
+      }
+      return createWrapper(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 = createWrapper(func, 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 = createWrapper(func, 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 an options object 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.
+     *
+     * 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 = 0,
+          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 || (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) {
+        clearTimeout(timerId);
+        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);
+        }
+        lastCallTime = lastInvokeTime = 0;
+        lastArgs = 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.
+            clearTimeout(timerId);
+            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 or more milliseconds.
+     */
+    var defer = rest(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 = rest(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 function.
+     * @example
+     *
+     * var flipped = _.flip(function() {
+     *   return _.toArray(arguments);
+     * });
+     *
+     * flipped('a', 'b', 'c', 'd');
+     * // => ['d', 'c', 'b', 'a']
+     */
+    function flip(func) {
+      return createWrapper(func, 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/6.0/#sec-properties-of-the-map-prototype-object)
+     * method interface of `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 memoizing 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 && 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);
+        return result;
+      };
+      memoized.cache = new (memoize.Cache || MapCache);
+      return memoized;
+    }
+
+    // Assign cache to `_.memoize`.
+    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 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() {
+        return !predicate.apply(this, arguments);
+      };
+    }
+
+    /**
+     * 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();
+     * // `initialize` invokes `createApplication` once
+     */
+    function once(func) {
+      return before(2, func);
+    }
+
+    /**
+     * Creates a function that invokes `func` with arguments transformed by
+     * corresponding `transforms`.
+     *
+     * @static
+     * @since 4.0.0
+     * @memberOf _
+     * @category Function
+     * @param {Function} func The function to wrap.
+     * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [transforms[_.identity]] The functions to transform.
+     * @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 = rest(function(func, transforms) {
+      transforms = (transforms.length == 1 && isArray(transforms[0]))
+        ? arrayMap(transforms[0], baseUnary(getIteratee()))
+        : arrayMap(baseFlatten(transforms, 1, isFlattenableIteratee), baseUnary(getIteratee()));
+
+      var funcsLength = transforms.length;
+      return rest(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
+     *
+     * var greet = function(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 = rest(function(func, partials) {
+      var holders = replaceHolders(partials, getPlaceholder(partial));
+      return createWrapper(func, 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
+     *
+     * var greet = function(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 = rest(function(func, partials) {
+      var holders = replaceHolders(partials, getPlaceholder(partialRight));
+      return createWrapper(func, 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 = rest(function(func, indexes) {
+      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
+    });
+
+    /**
+     * 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 = nativeMax(start === undefined ? (func.length - 1) : toInteger(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];
+        }
+        switch (start) {
+          case 0: return func.call(this, array);
+          case 1: return func.call(this, args[0], array);
+          case 2: return func.call(this, args[0], args[1], array);
+        }
+        var otherArgs = Array(start + 1);
+        index = -1;
+        while (++index < start) {
+          otherArgs[index] = args[index];
+        }
+        otherArgs[start] = array;
+        return apply(func, this, otherArgs);
+      };
+    }
+
+    /**
+     * 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/6.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 === undefined ? 0 : nativeMax(toInteger(start), 0);
+      return rest(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 an options object 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.
+     *
+     * 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 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 the wrapper function as its
+     * first argument. Any additional arguments provided to the function are
+     * appended to those provided to the wrapper function. 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) {
+      wrapper = wrapper == null ? identity : wrapper;
+      return partial(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, false, true);
+    }
+
+    /**
+     * 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) {
+      return baseClone(value, false, true, 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, true, true);
+    }
+
+    /**
+     * 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) {
+      return baseClone(value, true, true, customizer);
+    }
+
+    /**
+     * Performs a
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.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 = { 'user': 'fred' };
+     * var other = { 'user': 'fred' };
+     *
+     * _.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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isArguments(function() { return arguments; }());
+     * // => true
+     *
+     * _.isArguments([1, 2, 3]);
+     * // => false
+     */
+    function isArguments(value) {
+      // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+      return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+        (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+    }
+
+    /**
+     * Checks if `value` is classified as an `Array` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @type {Function}
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is correctly classified,
+     *  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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isArrayBuffer(new ArrayBuffer(2));
+     * // => true
+     *
+     * _.isArrayBuffer(new Array(2));
+     * // => false
+     */
+    function isArrayBuffer(value) {
+      return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
+    }
+
+    /**
+     * 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(getLength(value)) && !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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isBoolean(false);
+     * // => true
+     *
+     * _.isBoolean(null);
+     * // => false
+     */
+    function isBoolean(value) {
+      return value === true || value === false ||
+        (isObjectLike(value) && objectToString.call(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 = !Buffer ? constant(false) : function(value) {
+      return value instanceof Buffer;
+    };
+
+    /**
+     * 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isDate(new Date);
+     * // => true
+     *
+     * _.isDate('Mon April 23 2012');
+     * // => false
+     */
+    function isDate(value) {
+      return isObjectLike(value) && objectToString.call(value) == dateTag;
+    }
+
+    /**
+     * 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 !!value && value.nodeType === 1 && isObjectLike(value) && !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 (isArrayLike(value) &&
+          (isArray(value) || isString(value) || isFunction(value.splice) ||
+            isArguments(value) || isBuffer(value))) {
+        return !value.length;
+      }
+      if (isObjectLike(value)) {
+        var tag = getTag(value);
+        if (tag == mapTag || tag == setTag) {
+          return !value.size;
+        }
+      }
+      for (var key in value) {
+        if (hasOwnProperty.call(value, key)) {
+          return false;
+        }
+      }
+      return !(nonEnumShadows && keys(value).length);
+    }
+
+    /**
+     * 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 **not** supported.
+     *
+     * @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 = { 'user': 'fred' };
+     * var other = { 'user': 'fred' };
+     *
+     * _.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, 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;
+      }
+      return (objectToString.call(value) == errorTag) ||
+        (typeof value.message == 'string' && typeof value.name == 'string');
+    }
+
+    /**
+     * 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.MAX_VALUE);
+     * // => true
+     *
+     * _.isFinite(3.14);
+     * // => true
+     *
+     * _.isFinite(Infinity);
+     * // => 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isFunction(_);
+     * // => true
+     *
+     * _.isFunction(/abc/);
+     * // => false
+     */
+    function isFunction(value) {
+      // The use of `Object#toString` avoids issues with the `typeof` operator
+      // in Safari 8 which returns 'object' for typed array and weak map constructors,
+      // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+      var tag = isObject(value) ? objectToString.call(value) : '';
+      return tag == funcTag || tag == genTag;
+    }
+
+    /**
+     * 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 function is loosely based on
+     * [`ToLength`](http://ecma-international.org/ecma-262/6.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/6.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 && (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 && 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isMap(new Map);
+     * // => true
+     *
+     * _.isMap(new WeakMap);
+     * // => false
+     */
+    function isMap(value) {
+      return isObjectLike(value) && getTag(value) == mapTag;
+    }
+
+    /**
+     * Performs a partial deep comparison between `object` and `source` to
+     * determine if `object` contains equivalent property values. This method is
+     * equivalent to a `_.matches` function when `source` is partially applied.
+     *
+     * **Note:** This method supports comparing the same values as `_.isEqual`.
+     *
+     * @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 = { 'user': 'fred', 'age': 40 };
+     *
+     * _.isMatch(object, { 'age': 40 });
+     * // => true
+     *
+     * _.isMatch(object, { 'age': 36 });
+     * // => 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 native function.
+     *
+     * @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 (!isObject(value)) {
+        return false;
+      }
+      var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
+      return pattern.test(toSource(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 correctly classified,
+     *  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) && objectToString.call(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) ||
+          objectToString.call(value) != objectTag || isHostObject(value)) {
+        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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isRegExp(/abc/);
+     * // => true
+     *
+     * _.isRegExp('/abc/');
+     * // => false
+     */
+    function isRegExp(value) {
+      return isObject(value) && objectToString.call(value) == regexpTag;
+    }
+
+    /**
+     * 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isSet(new Set);
+     * // => true
+     *
+     * _.isSet(new WeakSet);
+     * // => false
+     */
+    function isSet(value) {
+      return isObjectLike(value) && getTag(value) == setTag;
+    }
+
+    /**
+     * 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isString('abc');
+     * // => true
+     *
+     * _.isString(1);
+     * // => false
+     */
+    function isString(value) {
+      return typeof value == 'string' ||
+        (!isArray(value) && isObjectLike(value) && objectToString.call(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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isSymbol(Symbol.iterator);
+     * // => true
+     *
+     * _.isSymbol('abc');
+     * // => false
+     */
+    function isSymbol(value) {
+      return typeof value == 'symbol' ||
+        (isObjectLike(value) && objectToString.call(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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isTypedArray(new Uint8Array);
+     * // => true
+     *
+     * _.isTypedArray([]);
+     * // => false
+     */
+    function isTypedArray(value) {
+      return isObjectLike(value) &&
+        isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
+    }
+
+    /**
+     * 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 correctly classified,
+     *  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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isWeakSet(new WeakSet);
+     * // => true
+     *
+     * _.isWeakSet(new Set);
+     * // => false
+     */
+    function isWeakSet(value) {
+      return isObjectLike(value) && objectToString.call(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 (iteratorSymbol && value[iteratorSymbol]) {
+        return iteratorToArray(value[iteratorSymbol]());
+      }
+      var tag = getTag(value),
+          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
+
+      return func(value);
+    }
+
+    /**
+     * Converts `value` to an integer.
+     *
+     * **Note:** This function is loosely based on
+     * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.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);
+     * // => 3
+     *
+     * _.toInteger(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toInteger(Infinity);
+     * // => 1.7976931348623157e+308
+     *
+     * _.toInteger('3');
+     * // => 3
+     */
+    function toInteger(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;
+      }
+      var remainder = value % 1;
+      return value === value ? (remainder ? value - remainder : value) : 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/6.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);
+     * // => 3
+     *
+     * _.toLength(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toLength(Infinity);
+     * // => 4294967295
+     *
+     * _.toLength('3');
+     * // => 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);
+     * // => 3
+     *
+     * _.toNumber(Number.MIN_VALUE);
+     * // => 5e-324
+     *
+     * _.toNumber(Infinity);
+     * // => Infinity
+     *
+     * _.toNumber('3');
+     * // => 3
+     */
+    function toNumber(value) {
+      if (typeof value == 'number') {
+        return value;
+      }
+      if (isSymbol(value)) {
+        return NAN;
+      }
+      if (isObject(value)) {
+        var other = isFunction(value.valueOf) ? 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);
+     * // => 3
+     *
+     * _.toSafeInteger(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toSafeInteger(Infinity);
+     * // => 9007199254740991
+     *
+     * _.toSafeInteger('3');
+     * // => 3
+     */
+    function toSafeInteger(value) {
+      return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
+    }
+
+    /**
+     * 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 process.
+     * @returns {string} Returns the 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.c = 3;
+     * }
+     *
+     * function Bar() {
+     *   this.e = 5;
+     * }
+     *
+     * Foo.prototype.d = 4;
+     * Bar.prototype.f = 6;
+     *
+     * _.assign({ 'a': 1 }, new Foo, new Bar);
+     * // => { 'a': 1, 'c': 3, 'e': 5 }
+     */
+    var assign = createAssigner(function(object, source) {
+      if (nonEnumShadows || 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.b = 2;
+     * }
+     *
+     * function Bar() {
+     *   this.d = 4;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     * Bar.prototype.e = 5;
+     *
+     * _.assignIn({ 'a': 1 }, new Foo, new Bar);
+     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
+     */
+    var assignIn = createAssigner(function(object, source) {
+      if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
+        copyObject(source, keysIn(source), object);
+        return;
+      }
+      for (var key in source) {
+        assignValue(object, key, source[key]);
+      }
+    });
+
+    /**
+     * 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 of elements to pick.
+     * @returns {Array} Returns the new array of picked elements.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+     *
+     * _.at(object, ['a[0].b.c', 'a[1]']);
+     * // => [3, 4]
+     *
+     * _.at(['a', 'b', 'c'], 0, 2);
+     * // => ['a', 'c']
+     */
+    var at = rest(function(object, paths) {
+      return baseAt(object, baseFlatten(paths, 1));
+    });
+
+    /**
+     * 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 ? baseAssign(result, properties) : result;
+    }
+
+    /**
+     * 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({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+     * // => { 'user': 'barney', 'age': 36 }
+     */
+    var defaults = rest(function(args) {
+      args.push(undefined, assignInDefaults);
+      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({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
+     * // => { 'user': { 'name': 'barney', 'age': 36 } }
+     *
+     */
+    var defaultsDeep = rest(function(args) {
+      args.push(undefined, mergeDefaults);
+      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 search.
+     * @param {Array|Function|Object|string} [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 baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
+    }
+
+    /**
+     * 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 search.
+     * @param {Array|Function|Object|string} [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 baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
+    }
+
+    /**
+     * 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), 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), 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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 new array of property 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 new array of property 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 used 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 {Array|Function|Object|string} [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 = rest(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/6.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) {
+      var isProto = isPrototype(object);
+      if (!(isProto || isArrayLike(object))) {
+        return baseKeys(object);
+      }
+      var indexes = indexKeys(object),
+          skipIndexes = !!indexes,
+          result = indexes || [],
+          length = result.length;
+
+      for (var key in object) {
+        if (baseHas(object, key) &&
+            !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+            !(isProto && key == 'constructor')) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * 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) {
+      var index = -1,
+          isProto = isPrototype(object),
+          props = baseKeysIn(object),
+          propsLength = props.length,
+          indexes = indexKeys(object),
+          skipIndexes = !!indexes,
+          result = indexes || [],
+          length = result.length;
+
+      while (++index < propsLength) {
+        var key = props[index];
+        if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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) {
+        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 {Array|Function|Object|string} [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) {
+        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 users = {
+     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
+     * };
+     *
+     * var ages = {
+     *   'data': [{ 'age': 36 }, { 'age': 40 }]
+     * };
+     *
+     * _.merge(users, ages);
+     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
+     */
+    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 seven 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 = {
+     *   'fruits': ['apple'],
+     *   'vegetables': ['beet']
+     * };
+     *
+     * var other = {
+     *   'fruits': ['banana'],
+     *   'vegetables': ['carrot']
+     * };
+     *
+     * _.mergeWith(object, other, customizer);
+     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
+     */
+    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 string keyed properties of `object` that are
+     * not omitted.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The source object.
+     * @param {...(string|string[])} [props] The property identifiers 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 = rest(function(object, props) {
+      if (object == null) {
+        return {};
+      }
+      props = arrayMap(baseFlatten(props, 1), toKey);
+      return basePick(object, baseDifference(getAllKeysIn(object), props));
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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) {
+      predicate = getIteratee(predicate);
+      return basePickBy(object, function(value, key) {
+        return !predicate(value, key);
+      });
+    }
+
+    /**
+     * 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[])} [props] The property identifiers 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 = rest(function(object, props) {
+      return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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) {
+      return object == null ? {} : basePickBy(object, getIteratee(predicate));
+    }
+
+    /**
+     * 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 = isKey(path, object) ? [path] : castPath(path);
+
+      var index = -1,
+          length = path.length;
+
+      // Ensure the loop is entered when path is empty.
+      if (!length) {
+        object = undefined;
+        length = 1;
+      }
+      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`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias entries
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the new array of 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)
+     */
+    function toPairs(object) {
+      return baseToPairs(object, keys(object));
+    }
+
+    /**
+     * Creates an array of own and inherited enumerable string keyed-value pairs
+     * for `object` which can be consumed by `_.fromPairs`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias entriesIn
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the new array of key-value pairs.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.toPairsIn(new Foo);
+     * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
+     */
+    function toPairsIn(object) {
+      return baseToPairs(object, keysIn(object));
+    }
+
+    /**
+     * 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. 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 {Array|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) || isTypedArray(object);
+      iteratee = getIteratee(iteratee, 4);
+
+      if (accumulator == null) {
+        if (isArr || isObject(object)) {
+          var Ctor = object.constructor;
+          if (isArr) {
+            accumulator = isArray(object) ? new Ctor : [];
+          } else {
+            accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
+          }
+        } else {
+          accumulator = {};
+        }
+      }
+      (isArr ? 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 ? 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 = toNumber(start) || 0;
+      if (end === undefined) {
+        end = start;
+        start = 0;
+      } else {
+        end = toNumber(end) || 0;
+      }
+      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 = toNumber(lower) || 0;
+        if (upper === undefined) {
+          upper = lower;
+          lower = 0;
+        } else {
+          upper = toNumber(upper) || 0;
+        }
+      }
+      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 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+     * 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(reLatin1, 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 search.
+     * @param {string} [target] The string to search for.
+     * @param {number} [position=string.length] The position to search from.
+     * @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);
+
+      position -= target.length;
+      return position >= 0 && string.indexOf(target, position) == position;
+    }
+
+    /**
+     * 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.
+     *
+     * Backticks are escaped because in IE < 9, they can break out of
+     * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
+     * [#133](https://html5sec.org/#133) of the
+     * [HTML5 Security Cheatsheet](https://html5sec.org/) 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) {
+      // Chrome fails to trim leading <BOM> whitespace characters.
+      // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details.
+      if (guard || radix == null) {
+        radix = 0;
+      } else if (radix) {
+        radix = +radix;
+      }
+      string = toString(string).replace(reTrim, '');
+      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
+    }
+
+    /**
+     * 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 : nativeReplace.call(string, 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 new array of 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 == '' && reHasComplexSymbol.test(string)) {
+          return castSlice(stringToArray(string), 0, limit);
+        }
+      }
+      return nativeSplit.call(string, 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 search.
+     * @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 = baseClamp(toInteger(position), 0, string.length);
+      return string.lastIndexOf(baseToString(target), position) == position;
+    }
+
+    /**
+     * 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 delimiter as an alternative to the default "interpolate" delimiter.
+     * var compiled = _.template('hello ${ user }!');
+     * compiled({ 'user': 'pebbles' });
+     * // => 'hello pebbles!'
+     *
+     * // Use custom template delimiters.
+     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
+     * var compiled = _.template('hello {{ user }}!');
+     * compiled({ 'user': 'mustache' });
+     * // => 'hello mustache!'
+     *
+     * // 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 the `source` property to inline compiled templates for meaningful
+     * // line numbers in error messages and stack traces.
+     * fs.writeFileSync(path.join(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, assignInDefaults);
+
+      var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
+          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 (reHasComplexSymbol.test(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;`, `&#39;`, and `&#96;` 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) {
+        pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
+      }
+      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 = rest(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',
+     *   'onClick': function() {
+     *     console.log('clicked ' + this.label);
+     *   }
+     * };
+     *
+     * _.bindAll(view, 'onClick');
+     * jQuery(element).on('click', view.onClick);
+     * // => Logs 'clicked docs' when clicked.
+     */
+    var bindAll = rest(function(object, methodNames) {
+      arrayEach(baseFlatten(methodNames, 1), function(key) {
+        key = toKey(key);
+        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 function.
+     * @example
+     *
+     * var func = _.cond([
+     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
+     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+     *   [_.constant(true),                _.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 ? pairs.length : 0,
+          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 rest(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`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {Object} source The object of property predicates to conform to.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36 },
+     *   { 'user': 'fred',   'age': 40 }
+     * ];
+     *
+     * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
+     * // => [{ 'user': 'fred', 'age': 40 }]
+     */
+    function conforms(source) {
+      return baseConforms(baseClone(source, true));
+    }
+
+    /**
+     * 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 function.
+     * @example
+     *
+     * var object = { 'user': 'fred' };
+     * var getter = _.constant(object);
+     *
+     * getter() === object;
+     * // => true
+     */
+    function constant(value) {
+      return function() {
+        return 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] Functions to invoke.
+     * @returns {Function} Returns the new 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] Functions to invoke.
+     * @returns {Function} Returns the new 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 given to it.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {*} value Any value.
+     * @returns {*} Returns `value`.
+     * @example
+     *
+     * var object = { 'user': 'fred' };
+     *
+     * _.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, true));
+    }
+
+    /**
+     * 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`. The created function is equivalent to
+     * `_.isMatch` with a `source` partially applied.
+     *
+     * **Note:** This method supports comparing the same values as `_.isEqual`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Util
+     * @param {Object} source The object of property values to match.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36, 'active': true },
+     *   { 'user': 'fred',   'age': 40, 'active': false }
+     * ];
+     *
+     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
+     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
+     */
+    function matches(source) {
+      return baseMatches(baseClone(source, true));
+    }
+
+    /**
+     * 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:** This method supports comparing the same values as `_.isEqual`.
+     *
+     * @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 function.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney' },
+     *   { 'user': 'fred' }
+     * ];
+     *
+     * _.find(users, _.matchesProperty('user', 'fred'));
+     * // => { 'user': 'fred' }
+     */
+    function matchesProperty(path, srcValue) {
+      return baseMatchesProperty(path, baseClone(srcValue, true));
+    }
+
+    /**
+     * 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 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 = rest(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 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 = rest(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;
+    }
+
+    /**
+     * A no-operation function that returns `undefined` regardless of the
+     * arguments it receives.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.3.0
+     * @category Util
+     * @example
+     *
+     * var object = { 'user': 'fred' };
+     *
+     * _.noop(object) === undefined;
+     * // => true
+     */
+    function noop() {
+      // No operation performed.
+    }
+
+    /**
+     * Creates a function that returns its nth argument. 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 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 rest(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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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 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 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 new array 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 new array 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);
+
+    /**
+     * 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(true));
+     * // => [true, true, true, true]
+     */
+    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']
+     *
+     * var path = ['a', 'b', 'c'],
+     *     newPath = _.toPath(path);
+     *
+     * console.log(newPath);
+     * // => ['a', 'b', 'c']
+     *
+     * console.log(path === newPath);
+     * // => false
+     */
+    function toPath(value) {
+      if (isArray(value)) {
+        return arrayMap(value, toKey);
+      }
+      return isSymbol(value) ? [value] : copyArray(stringToPath(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;
+    });
+
+    /**
+     * 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;
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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), 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 {Array|Function|Object|string} [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));
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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), 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;
+    });
+
+    /**
+     * 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;
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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))
+        : 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.deburr = deburr;
+    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.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.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) {
+        var filtered = this.__filtered__;
+        if (filtered && !index) {
+          return new LazyWrapper(this);
+        }
+        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
+
+        var result = this.clone();
+        if (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 = rest(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) {
+      predicate = getIteratee(predicate, 3);
+      return this.filter(function(value) {
+        return !predicate(value);
+      });
+    };
+
+    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[createHybridWrapper(undefined, 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;
+
+    if (iteratorSymbol) {
+      lodash.prototype[iteratorSymbol] = wrapperToIterator;
+    }
+    return lodash;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // Export lodash.
+  var _ = runInContext();
+
+  // Expose Lodash on the free variable `window` or `self` when available so it's
+  // globally accessible, even when bundled with Browserify, Webpack, etc. This
+  // also prevents errors in cases where 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.
+  (freeWindow || freeSelf || {})._ = _;
+
+  // Some AMD build optimizers like r.js check for condition patterns like the following:
+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+    // Define as an anonymous module so, through path mapping, it can be
+    // referenced as the "underscore" module.
+    define(function() {
+      return _;
+    });
+  }
+  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
+  else if (freeExports && freeModule) {
+    // Export for Node.js.
+    if (moduleExports) {
+      (freeModule.exports = _)._ = _;
+    }
+    // Export for CommonJS support.
+    freeExports._ = _;
+  }
+  else {
+    // Export to the global object.
+    root._ = _;
+  }
+}.call(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.min.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.min.js
new file mode 100644
index 0000000..4994229
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/lodash.min.js
@@ -0,0 +1,126 @@
+/**
+ * @license
+ * lodash 4.11.2 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
+ * Build: `lodash -o ./dist/lodash.js`
+ */
+;(function(){function t(t,n){return t.set(n[0],n[1]),t}function n(t,n){return t.add(n),t}function r(t,n,r){switch(r.length){case 0:return t.call(n);case 1:return t.call(n,r[0]);case 2:return t.call(n,r[0],r[1]);case 3:return t.call(n,r[0],r[1],r[2])}return t.apply(n,r)}function e(t,n,r,e){for(var u=-1,o=t.length;++u<o;){var i=t[u];n(e,i,r(i),t)}return e}function u(t,n){for(var r=-1,e=t.length;++r<e&&false!==n(t[r],r,t););return t}function o(t,n){for(var r=-1,e=t.length;++r<e;)if(!n(t[r],r,t))return false;
+return true}function i(t,n){for(var r=-1,e=t.length,u=0,o=[];++r<e;){var i=t[r];n(i,r,t)&&(o[u++]=i)}return o}function f(t,n){return!!t.length&&-1<g(t,n,0)}function c(t,n,r){for(var e=-1,u=t.length;++e<u;)if(r(n,t[e]))return true;return false}function a(t,n){for(var r=-1,e=t.length,u=Array(e);++r<e;)u[r]=n(t[r],r,t);return u}function l(t,n){for(var r=-1,e=n.length,u=t.length;++r<e;)t[u+r]=n[r];return t}function s(t,n,r,e){var u=-1,o=t.length;for(e&&o&&(r=t[++u]);++u<o;)r=n(r,t[u],u,t);return r}function h(t,n,r,e){
+var u=t.length;for(e&&u&&(r=t[--u]);u--;)r=n(r,t[u],u,t);return r}function p(t,n){for(var r=-1,e=t.length;++r<e;)if(n(t[r],r,t))return true;return false}function _(t,n,r,e){var u;return r(t,function(t,r,o){return n(t,r,o)?(u=e?r:t,false):void 0}),u}function v(t,n,r){for(var e=t.length,u=r?e:-1;r?u--:++u<e;)if(n(t[u],u,t))return u;return-1}function g(t,n,r){if(n!==n)return B(t,r);--r;for(var e=t.length;++r<e;)if(t[r]===n)return r;return-1}function d(t,n,r,e){--r;for(var u=t.length;++r<u;)if(e(t[r],n))return r;
+return-1}function y(t,n){var r=t?t.length:0;return r?j(t,n)/r:Z}function b(t,n,r,e,u){return u(t,function(t,u,o){r=e?(e=false,t):n(r,t,u,o)}),r}function x(t,n){var r=t.length;for(t.sort(n);r--;)t[r]=t[r].c;return t}function j(t,n){for(var r,e=-1,u=t.length;++e<u;){var o=n(t[e]);o!==N&&(r=r===N?o:r+o)}return r}function m(t,n){for(var r=-1,e=Array(t);++r<t;)e[r]=n(r);return e}function w(t,n){return a(n,function(n){return[n,t[n]]})}function A(t){return function(n){return t(n)}}function O(t,n){return a(n,function(n){
+return t[n]})}function k(t,n){for(var r=-1,e=t.length;++r<e&&-1<g(n,t[r],0););return r}function E(t,n){for(var r=t.length;r--&&-1<g(n,t[r],0););return r}function I(t){return t&&t.Object===Object?t:null}function S(t){return Lt[t]}function R(t){return Ct[t]}function W(t){return"\\"+zt[t]}function B(t,n,r){var e=t.length;for(n+=r?0:-1;r?n--:++n<e;){var u=t[n];if(u!==u)return n}return-1}function L(t){var n=false;if(null!=t&&typeof t.toString!="function")try{n=!!(t+"")}catch(r){}return n}function C(t){for(var n,r=[];!(n=t.next()).done;)r.push(n.value);
+return r}function M(t){var n=-1,r=Array(t.size);return t.forEach(function(t,e){r[++n]=[e,t]}),r}function U(t,n){for(var r=-1,e=t.length,u=0,o=[];++r<e;){var i=t[r];i!==n&&"__lodash_placeholder__"!==i||(t[r]="__lodash_placeholder__",o[u++]=r)}return o}function z(t){var n=-1,r=Array(t.size);return t.forEach(function(t){r[++n]=t}),r}function D(t){if(!t||!It.test(t))return t.length;for(var n=kt.lastIndex=0;kt.test(t);)n++;return n}function $(t){return Mt[t]}function F(I){function jt(t){if(De(t)&&!li(t)&&!(t instanceof Lt)){
+if(t instanceof wt)return t;if(wu.call(t,"__wrapped__"))return oe(t)}return new wt(t)}function mt(){}function wt(t,n){this.__wrapped__=t,this.__actions__=[],this.__chain__=!!n,this.__index__=0,this.__values__=N}function Lt(t){this.__wrapped__=t,this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Ct(){}function Mt(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function Ut(t){var n=-1,r=t?t.length:0;
+for(this.__data__=new Mt;++n<r;)this.push(t[n])}function zt(t,n){var r=t.__data__;return Hr(n)?(r=r.__data__,"__lodash_hash_undefined__"===(typeof n=="string"?r.string:r.hash)[n]):r.has(n)}function Ft(t){var n=-1,r=t?t.length:0;for(this.clear();++n<r;){var e=t[n];this.set(e[0],e[1])}}function Nt(t,n){var r=Tt(t,n);return 0>r?false:(r==t.length-1?t.pop():Fu.call(t,r,1),true)}function Zt(t,n){var r=Tt(t,n);return 0>r?N:t[r][1]}function Tt(t,n){for(var r=t.length;r--;)if(Se(t[r][0],n))return r;return-1}function qt(t,n,r){
+var e=Tt(t,n);0>e?t.push([n,r]):t[e][1]=r}function Gt(t,n,r,e){return t===N||Se(t,xu[r])&&!wu.call(e,r)?n:t}function Jt(t,n,r){(r===N||Se(t[n],r))&&(typeof n!="number"||r!==N||n in t)||(t[n]=r)}function Yt(t,n,r){var e=t[n];wu.call(t,n)&&Se(e,r)&&(r!==N||n in t)||(t[n]=r)}function Ht(t,n,r,e){return yo(t,function(t,u,o){n(e,t,r(t),o)}),e}function Qt(t,n){return t&&ar(n,tu(n),t)}function Xt(t,n){for(var r=-1,e=null==t,u=n.length,o=Array(u);++r<u;)o[r]=e?N:Qe(t,n[r]);return o}function tn(t,n,r){return t===t&&(r!==N&&(t=r>=t?t:r),
+n!==N&&(t=t>=n?t:n)),t}function nn(t,n,r,e,o,i,f){var c;if(e&&(c=i?e(t,o,i,f):e(t)),c!==N)return c;if(!ze(t))return t;if(o=li(t)){if(c=Pr(t),!n)return cr(t,c)}else{var a=Fr(t),l="[object Function]"==a||"[object GeneratorFunction]"==a;if(si(t))return er(t,n);if("[object Object]"==a||"[object Arguments]"==a||l&&!i){if(L(t))return i?t:{};if(c=Zr(l?{}:t),!n)return lr(t,Qt(c,t))}else{if(!Bt[a])return i?t:{};c=Tr(t,a,nn,n)}}if(f||(f=new Ft),i=f.get(t))return i;if(f.set(t,c),!o)var s=r?vn(t,tu,$r):tu(t);
+return u(s||t,function(u,o){s&&(o=u,u=t[o]),Yt(c,o,nn(u,n,r,e,o,t,f))}),c}function rn(t){var n=tu(t),r=n.length;return function(e){if(null==e)return!r;for(var u=r;u--;){var o=n[u],i=t[o],f=e[o];if(f===N&&!(o in Object(e))||!i(f))return false}return true}}function en(t){return ze(t)?zu(t):{}}function un(t,n,r){if(typeof t!="function")throw new yu("Expected a function");return $u(function(){t.apply(N,r)},n)}function on(t,n,r,e){var u=-1,o=f,i=true,l=t.length,s=[],h=n.length;if(!l)return s;r&&(n=a(n,A(r))),e?(o=c,
+i=false):n.length>=200&&(o=zt,i=false,n=new Ut(n));t:for(;++u<l;){var p=t[u],_=r?r(p):p,p=e||0!==p?p:0;if(i&&_===_){for(var v=h;v--;)if(n[v]===_)continue t;s.push(p)}else o(n,_,e)||s.push(p)}return s}function fn(t,n){var r=true;return yo(t,function(t,e,u){return r=!!n(t,e,u)}),r}function cn(t,n,r){for(var e=-1,u=t.length;++e<u;){var o=t[e],i=n(o);if(null!=i&&(f===N?i===i&&!Te(i):r(i,f)))var f=i,c=o}return c}function an(t,n){var r=[];return yo(t,function(t,e,u){n(t,e,u)&&r.push(t)}),r}function ln(t,n,r,e,u){
+var o=-1,i=t.length;for(r||(r=Vr),u||(u=[]);++o<i;){var f=t[o];n>0&&r(f)?n>1?ln(f,n-1,r,e,u):l(u,f):e||(u[u.length]=f)}return u}function sn(t,n){return t&&xo(t,n,tu)}function hn(t,n){return t&&jo(t,n,tu)}function pn(t,n){return i(n,function(n){return Ce(t[n])})}function _n(t,n){n=Yr(n,t)?[n]:nr(n);for(var r=0,e=n.length;null!=t&&e>r;)t=t[ee(n[r++])];return r&&r==e?t:N}function vn(t,n,r){return n=n(t),li(t)?n:l(n,r(t))}function gn(t,n){return t>n}function dn(t,n){return wu.call(t,n)||typeof t=="object"&&n in t&&null===Zu(Object(t));
+}function yn(t,n){return n in Object(t)}function bn(t,n,r){for(var e=r?c:f,u=t[0].length,o=t.length,i=o,l=Array(o),s=1/0,h=[];i--;){var p=t[i];i&&n&&(p=a(p,A(n))),s=Gu(p.length,s),l[i]=!r&&(n||u>=120&&p.length>=120)?new Ut(i&&p):N}var p=t[0],_=-1,v=l[0];t:for(;++_<u&&s>h.length;){var g=p[_],d=n?n(g):g,g=r||0!==g?g:0;if(v?!zt(v,d):!e(h,d,r)){for(i=o;--i;){var y=l[i];if(y?!zt(y,d):!e(t[i],d,r))continue t}v&&v.push(d),h.push(g)}}return h}function xn(t,n,r){var e={};return sn(t,function(t,u,o){n(e,r(t),u,o);
+}),e}function jn(t,n,e){return Yr(n,t)||(n=nr(n),t=re(t,n),n=ae(n)),n=null==t?t:t[ee(n)],null==n?N:r(n,t,e)}function mn(t,n,r,e,u){if(t===n)n=true;else if(null==t||null==n||!ze(t)&&!De(n))n=t!==t&&n!==n;else t:{var o=li(t),i=li(n),f="[object Array]",c="[object Array]";o||(f=Fr(t),f="[object Arguments]"==f?"[object Object]":f),i||(c=Fr(n),c="[object Arguments]"==c?"[object Object]":c);var a="[object Object]"==f&&!L(t),i="[object Object]"==c&&!L(n);if((c=f==c)&&!a)u||(u=new Ft),n=o||qe(t)?Br(t,n,mn,r,e,u):Lr(t,n,f,mn,r,e,u);else{
+if(!(2&e)&&(o=a&&wu.call(t,"__wrapped__"),f=i&&wu.call(n,"__wrapped__"),o||f)){t=o?t.value():t,n=f?n.value():n,u||(u=new Ft),n=mn(t,n,r,e,u);break t}if(c)n:if(u||(u=new Ft),o=2&e,f=tu(t),i=f.length,c=tu(n).length,i==c||o){for(a=i;a--;){var l=f[a];if(!(o?l in n:dn(n,l))){n=false;break n}}if(c=u.get(t))n=c==n;else{c=true,u.set(t,n);for(var s=o;++a<i;){var l=f[a],h=t[l],p=n[l];if(r)var _=o?r(p,h,l,n,t,u):r(h,p,l,t,n,u);if(_===N?h!==p&&!mn(h,p,r,e,u):!_){c=false;break}s||(s="constructor"==l)}c&&!s&&(r=t.constructor,
+e=n.constructor,r!=e&&"constructor"in t&&"constructor"in n&&!(typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)&&(c=false)),u["delete"](t),n=c}}else n=false;else n=false}}return n}function wn(t,n,r,e){var u=r.length,o=u,i=!e;if(null==t)return!o;for(t=Object(t);u--;){var f=r[u];if(i&&f[2]?f[1]!==t[f[0]]:!(f[0]in t))return false}for(;++u<o;){var f=r[u],c=f[0],a=t[c],l=f[1];if(i&&f[2]){if(a===N&&!(c in t))return false}else{if(f=new Ft,e)var s=e(a,l,c,t,n,f);if(s===N?!mn(l,a,e,3,f):!s)return false;
+}}return true}function An(t){return typeof t=="function"?t:null==t?au:typeof t=="object"?li(t)?Sn(t[0],t[1]):In(t):pu(t)}function On(t){t=null==t?t:Object(t);var n,r=[];for(n in t)r.push(n);return r}function kn(t,n){return n>t}function En(t,n){var r=-1,e=We(t)?Array(t.length):[];return yo(t,function(t,u,o){e[++r]=n(t,u,o)}),e}function In(t){var n=Ur(t);return 1==n.length&&n[0][2]?te(n[0][0],n[0][1]):function(r){return r===t||wn(r,t,n)}}function Sn(t,n){return Yr(t)&&n===n&&!ze(n)?te(ee(t),n):function(r){
+var e=Qe(r,t);return e===N&&e===n?Xe(r,t):mn(n,e,N,3)}}function Rn(t,n,r,e,o){if(t!==n){if(!li(n)&&!qe(n))var i=nu(n);u(i||n,function(u,f){if(i&&(f=u,u=n[f]),ze(u)){o||(o=new Ft);var c=f,a=o,l=t[c],s=n[c],h=a.get(s);if(h)Jt(t,c,h);else{var h=e?e(l,s,c+"",t,n,a):N,p=h===N;p&&(h=s,li(s)||qe(s)?li(l)?h=l:Be(l)?h=cr(l):(p=false,h=nn(s,true)):Ne(s)||Re(s)?Re(l)?h=Ye(l):!ze(l)||r&&Ce(l)?(p=false,h=nn(s,true)):h=l:p=false),a.set(s,h),p&&Rn(h,s,r,e,a),a["delete"](s),Jt(t,c,h)}}else c=e?e(t[f],u,f+"",t,n,o):N,c===N&&(c=u),
+Jt(t,f,c)})}}function Wn(t,n){var r=t.length;return r?(n+=0>n?r:0,Gr(n,r)?t[n]:N):void 0}function Bn(t,n,r){var e=-1;return n=a(n.length?n:[au],A(Mr())),t=En(t,function(t){return{a:a(n,function(n){return n(t)}),b:++e,c:t}}),x(t,function(t,n){var e;t:{e=-1;for(var u=t.a,o=n.a,i=u.length,f=r.length;++e<i;){var c=or(u[e],o[e]);if(c){e=e>=f?c:c*("desc"==r[e]?-1:1);break t}}e=t.b-n.b}return e})}function Ln(t,n){return t=Object(t),s(n,function(n,r){return r in t&&(n[r]=t[r]),n},{})}function Cn(t,n){for(var r=-1,e=vn(t,nu,ko),u=e.length,o={};++r<u;){
+var i=e[r],f=t[i];n(f,i)&&(o[i]=f)}return o}function Mn(t){return function(n){return null==n?N:n[t]}}function Un(t){return function(n){return _n(n,t)}}function zn(t,n,r,e){var u=e?d:g,o=-1,i=n.length,f=t;for(r&&(f=a(t,A(r)));++o<i;)for(var c=0,l=n[o],l=r?r(l):l;-1<(c=u(f,l,c,e));)f!==t&&Fu.call(f,c,1),Fu.call(t,c,1);return t}function Dn(t,n){for(var r=t?n.length:0,e=r-1;r--;){var u=n[r];if(r==e||u!==o){var o=u;if(Gr(u))Fu.call(t,u,1);else if(Yr(u,t))delete t[ee(u)];else{var u=nr(u),i=re(t,u);null!=i&&delete i[ee(ae(u))];
+}}}}function $n(t,n){return t+Pu(Yu()*(n-t+1))}function Fn(t,n){var r="";if(!t||1>n||n>9007199254740991)return r;do n%2&&(r+=t),(n=Pu(n/2))&&(t+=t);while(n);return r}function Nn(t,n,r,e){n=Yr(n,t)?[n]:nr(n);for(var u=-1,o=n.length,i=o-1,f=t;null!=f&&++u<o;){var c=ee(n[u]);if(ze(f)){var a=r;if(u!=i){var l=f[c],a=e?e(l,c,f):N;a===N&&(a=null==l?Gr(n[u+1])?[]:{}:l)}Yt(f,c,a)}f=f[c]}return t}function Pn(t,n,r){var e=-1,u=t.length;for(0>n&&(n=-n>u?0:u+n),r=r>u?u:r,0>r&&(r+=u),u=n>r?0:r-n>>>0,n>>>=0,r=Array(u);++e<u;)r[e]=t[e+n];
+return r}function Zn(t,n){var r;return yo(t,function(t,e,u){return r=n(t,e,u),!r}),!!r}function Tn(t,n,r){var e=0,u=t?t.length:e;if(typeof n=="number"&&n===n&&2147483647>=u){for(;u>e;){var o=e+u>>>1,i=t[o];null!==i&&!Te(i)&&(r?n>=i:n>i)?e=o+1:u=o}return u}return qn(t,n,au,r)}function qn(t,n,r,e){n=r(n);for(var u=0,o=t?t.length:0,i=n!==n,f=null===n,c=Te(n),a=n===N;o>u;){var l=Pu((u+o)/2),s=r(t[l]),h=s!==N,p=null===s,_=s===s,v=Te(s);(i?e||_:a?_&&(e||h):f?_&&h&&(e||!p):c?_&&h&&!p&&(e||!v):p||v?0:e?n>=s:n>s)?u=l+1:o=l;
+}return Gu(o,4294967294)}function Vn(t,n){for(var r=-1,e=t.length,u=0,o=[];++r<e;){var i=t[r],f=n?n(i):i;if(!r||!Se(f,c)){var c=f;o[u++]=0===i?0:i}}return o}function Kn(t){return typeof t=="number"?t:Te(t)?Z:+t}function Gn(t){if(typeof t=="string")return t;if(Te(t))return go?go.call(t):"";var n=t+"";return"0"==n&&1/t==-P?"-0":n}function Jn(t,n,r){var e=-1,u=f,o=t.length,i=true,a=[],l=a;if(r)i=false,u=c;else if(o>=200){if(u=n?null:wo(t))return z(u);i=false,u=zt,l=new Ut}else l=n?[]:a;t:for(;++e<o;){var s=t[e],h=n?n(s):s,s=r||0!==s?s:0;
+if(i&&h===h){for(var p=l.length;p--;)if(l[p]===h)continue t;n&&l.push(h),a.push(s)}else u(l,h,r)||(l!==a&&l.push(h),a.push(s))}return a}function Yn(t,n,r,e){for(var u=t.length,o=e?u:-1;(e?o--:++o<u)&&n(t[o],o,t););return r?Pn(t,e?0:o,e?o+1:u):Pn(t,e?o+1:0,e?u:o)}function Hn(t,n){var r=t;return r instanceof Lt&&(r=r.value()),s(n,function(t,n){return n.func.apply(n.thisArg,l([t],n.args))},r)}function Qn(t,n,r){for(var e=-1,u=t.length;++e<u;)var o=o?l(on(o,t[e],n,r),on(t[e],o,n,r)):t[e];return o&&o.length?Jn(o,n,r):[];
+}function Xn(t,n,r){for(var e=-1,u=t.length,o=n.length,i={};++e<u;)r(i,t[e],o>e?n[e]:N);return i}function tr(t){return Be(t)?t:[]}function nr(t){return li(t)?t:Io(t)}function rr(t,n,r){var e=t.length;return r=r===N?e:r,!n&&r>=e?t:Pn(t,n,r)}function er(t,n){if(n)return t.slice();var r=new t.constructor(t.length);return t.copy(r),r}function ur(t){var n=new t.constructor(t.byteLength);return new Bu(n).set(new Bu(t)),n}function or(t,n){if(t!==n){var r=t!==N,e=null===t,u=t===t,o=Te(t),i=n!==N,f=null===n,c=n===n,a=Te(n);
+if(!f&&!a&&!o&&t>n||o&&i&&c&&!f&&!a||e&&i&&c||!r&&c||!u)return 1;if(!e&&!o&&!a&&n>t||a&&r&&u&&!e&&!o||f&&r&&u||!i&&u||!c)return-1}return 0}function ir(t,n,r,e){var u=-1,o=t.length,i=r.length,f=-1,c=n.length,a=Ku(o-i,0),l=Array(c+a);for(e=!e;++f<c;)l[f]=n[f];for(;++u<i;)(e||o>u)&&(l[r[u]]=t[u]);for(;a--;)l[f++]=t[u++];return l}function fr(t,n,r,e){var u=-1,o=t.length,i=-1,f=r.length,c=-1,a=n.length,l=Ku(o-f,0),s=Array(l+a);for(e=!e;++u<l;)s[u]=t[u];for(l=u;++c<a;)s[l+c]=n[c];for(;++i<f;)(e||o>u)&&(s[l+r[i]]=t[u++]);
+return s}function cr(t,n){var r=-1,e=t.length;for(n||(n=Array(e));++r<e;)n[r]=t[r];return n}function ar(t,n,r,e){r||(r={});for(var u=-1,o=n.length;++u<o;){var i=n[u],f=e?e(r[i],t[i],i,r,t):t[i];Yt(r,i,f)}return r}function lr(t,n){return ar(t,$r(t),n)}function sr(t,n){return function(r,u){var o=li(r)?e:Ht,i=n?n():{};return o(r,t,Mr(u),i)}}function hr(t){return Ee(function(n,r){var e=-1,u=r.length,o=u>1?r[u-1]:N,i=u>2?r[2]:N,o=typeof o=="function"?(u--,o):N;for(i&&Jr(r[0],r[1],i)&&(o=3>u?N:o,u=1),n=Object(n);++e<u;)(i=r[e])&&t(n,i,e,o);
+return n})}function pr(t,n){return function(r,e){if(null==r)return r;if(!We(r))return t(r,e);for(var u=r.length,o=n?u:-1,i=Object(r);(n?o--:++o<u)&&false!==e(i[o],o,i););return r}}function _r(t){return function(n,r,e){var u=-1,o=Object(n);e=e(n);for(var i=e.length;i--;){var f=e[t?i:++u];if(false===r(o[f],f,o))break}return n}}function vr(t,n,r){function e(){return(this&&this!==Vt&&this instanceof e?o:t).apply(u?r:this,arguments)}var u=1&n,o=yr(t);return e}function gr(t){return function(n){n=He(n);var r=It.test(n)?n.match(kt):N,e=r?r[0]:n.charAt(0);
+return n=r?rr(r,1).join(""):n.slice(1),e[t]()+n}}function dr(t){return function(n){return s(fu(iu(n).replace(At,"")),t,"")}}function yr(t){return function(){var n=arguments;switch(n.length){case 0:return new t;case 1:return new t(n[0]);case 2:return new t(n[0],n[1]);case 3:return new t(n[0],n[1],n[2]);case 4:return new t(n[0],n[1],n[2],n[3]);case 5:return new t(n[0],n[1],n[2],n[3],n[4]);case 6:return new t(n[0],n[1],n[2],n[3],n[4],n[5]);case 7:return new t(n[0],n[1],n[2],n[3],n[4],n[5],n[6])}var r=en(t.prototype),n=t.apply(r,n);
+return ze(n)?n:r}}function br(t,n,e){function u(){for(var i=arguments.length,f=Array(i),c=i,a=Dr(u);c--;)f[c]=arguments[c];return c=3>i&&f[0]!==a&&f[i-1]!==a?[]:U(f,a),i-=c.length,e>i?Sr(t,n,jr,u.placeholder,N,f,c,N,N,e-i):r(this&&this!==Vt&&this instanceof u?o:t,this,f)}var o=yr(t);return u}function xr(t){return Ee(function(n){n=ln(n,1);var r=n.length,e=r,u=wt.prototype.thru;for(t&&n.reverse();e--;){var o=n[e];if(typeof o!="function")throw new yu("Expected a function");if(u&&!i&&"wrapper"==Cr(o))var i=new wt([],true);
+}for(e=i?e:r;++e<r;)var o=n[e],u=Cr(o),f="wrapper"==u?Ao(o):N,i=f&&Qr(f[0])&&424==f[1]&&!f[4].length&&1==f[9]?i[Cr(f[0])].apply(i,f[3]):1==o.length&&Qr(o)?i[u]():i.thru(o);return function(){var t=arguments,e=t[0];if(i&&1==t.length&&li(e)&&e.length>=200)return i.plant(e).value();for(var u=0,t=r?n[u].apply(this,t):e;++u<r;)t=n[u].call(this,t);return t}})}function jr(t,n,r,e,u,o,i,f,c,a){function l(){for(var d=arguments.length,y=d,b=Array(d);y--;)b[y]=arguments[y];if(_){var x,j=Dr(l),y=b.length;for(x=0;y--;)b[y]===j&&x++;
+}if(e&&(b=ir(b,e,u,_)),o&&(b=fr(b,o,i,_)),d-=x,_&&a>d)return j=U(b,j),Sr(t,n,jr,l.placeholder,r,b,j,f,c,a-d);if(j=h?r:this,y=p?j[t]:t,d=b.length,f){x=b.length;for(var m=Gu(f.length,x),w=cr(b);m--;){var A=f[m];b[m]=Gr(A,x)?w[A]:N}}else v&&d>1&&b.reverse();return s&&d>c&&(b.length=c),this&&this!==Vt&&this instanceof l&&(y=g||yr(y)),y.apply(j,b)}var s=128&n,h=1&n,p=2&n,_=24&n,v=512&n,g=p?N:yr(t);return l}function mr(t,n){return function(r,e){return xn(r,t,n(e))}}function wr(t){return function(n,r){var e;
+if(n===N&&r===N)return 0;if(n!==N&&(e=n),r!==N){if(e===N)return r;typeof n=="string"||typeof r=="string"?(n=Gn(n),r=Gn(r)):(n=Kn(n),r=Kn(r)),e=t(n,r)}return e}}function Ar(t){return Ee(function(n){return n=1==n.length&&li(n[0])?a(n[0],A(Mr())):a(ln(n,1,Kr),A(Mr())),Ee(function(e){var u=this;return t(n,function(t){return r(t,u,e)})})})}function Or(t,n){n=n===N?" ":Gn(n);var r=n.length;return 2>r?r?Fn(n,t):n:(r=Fn(n,Nu(t/D(n))),It.test(n)?rr(r.match(kt),0,t).join(""):r.slice(0,t))}function kr(t,n,e,u){
+function o(){for(var n=-1,c=arguments.length,a=-1,l=u.length,s=Array(l+c),h=this&&this!==Vt&&this instanceof o?f:t;++a<l;)s[a]=u[a];for(;c--;)s[a++]=arguments[++n];return r(h,i?e:this,s)}var i=1&n,f=yr(t);return o}function Er(t){return function(n,r,e){e&&typeof e!="number"&&Jr(n,r,e)&&(r=e=N),n=Je(n),n=n===n?n:0,r===N?(r=n,n=0):r=Je(r)||0,e=e===N?r>n?1:-1:Je(e)||0;var u=-1;r=Ku(Nu((r-n)/(e||1)),0);for(var o=Array(r);r--;)o[t?r:++u]=n,n+=e;return o}}function Ir(t){return function(n,r){return typeof n=="string"&&typeof r=="string"||(n=Je(n),
+r=Je(r)),t(n,r)}}function Sr(t,n,r,e,u,o,i,f,c,a){var l=8&n,s=l?i:N;i=l?N:i;var h=l?o:N;return o=l?N:o,n=(n|(l?32:64))&~(l?64:32),4&n||(n&=-4),n=[t,n,u,h,s,o,i,f,c,a],r=r.apply(N,n),Qr(t)&&Eo(r,n),r.placeholder=e,r}function Rr(t){var n=gu[t];return function(t,r){if(t=Je(t),r=Ke(r)){var e=(He(t)+"e").split("e"),e=n(e[0]+"e"+(+e[1]+r)),e=(He(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return n(t)}}function Wr(t,n,r,e,u,o,i,f){var c=2&n;if(!c&&typeof t!="function")throw new yu("Expected a function");
+var a=e?e.length:0;if(a||(n&=-97,e=u=N),i=i===N?i:Ku(Ke(i),0),f=f===N?f:Ke(f),a-=u?u.length:0,64&n){var l=e,s=u;e=u=N}var h=c?N:Ao(t);return o=[t,n,r,e,u,l,s,o,i,f],h&&(r=o[1],t=h[1],n=r|t,e=128==t&&8==r||128==t&&256==r&&h[8]>=o[7].length||384==t&&h[8]>=h[7].length&&8==r,131>n||e)&&(1&t&&(o[2]=h[2],n|=1&r?0:4),(r=h[3])&&(e=o[3],o[3]=e?ir(e,r,h[4]):r,o[4]=e?U(o[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=o[5],o[5]=e?fr(e,r,h[6]):r,o[6]=e?U(o[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(o[7]=r),
+128&t&&(o[8]=null==o[8]?h[8]:Gu(o[8],h[8])),null==o[9]&&(o[9]=h[9]),o[0]=h[0],o[1]=n),t=o[0],n=o[1],r=o[2],e=o[3],u=o[4],f=o[9]=null==o[9]?c?0:t.length:Ku(o[9]-a,0),!f&&24&n&&(n&=-25),(h?mo:Eo)(n&&1!=n?8==n||16==n?br(t,n,f):32!=n&&33!=n||u.length?jr.apply(N,o):kr(t,n,r,e):vr(t,n,r),o)}function Br(t,n,r,e,u,o){var i=-1,f=2&u,c=1&u,a=t.length,l=n.length;if(a!=l&&!(f&&l>a))return false;if(l=o.get(t))return l==n;for(l=true,o.set(t,n);++i<a;){var s=t[i],h=n[i];if(e)var _=f?e(h,s,i,n,t,o):e(s,h,i,t,n,o);if(_!==N){
+if(_)continue;l=false;break}if(c){if(!p(n,function(t){return s===t||r(s,t,e,u,o)})){l=false;break}}else if(s!==h&&!r(s,h,e,u,o)){l=false;break}}return o["delete"](t),l}function Lr(t,n,r,e,u,o,i){switch(r){case"[object DataView]":if(t.byteLength!=n.byteLength||t.byteOffset!=n.byteOffset)break;t=t.buffer,n=n.buffer;case"[object ArrayBuffer]":if(t.byteLength!=n.byteLength||!e(new Bu(t),new Bu(n)))break;return true;case"[object Boolean]":case"[object Date]":return+t==+n;case"[object Error]":return t.name==n.name&&t.message==n.message;
+case"[object Number]":return t!=+t?n!=+n:t==+n;case"[object RegExp]":case"[object String]":return t==n+"";case"[object Map]":var f=M;case"[object Set]":if(f||(f=z),t.size!=n.size&&!(2&o))break;return(r=i.get(t))?r==n:(o|=1,i.set(t,n),Br(f(t),f(n),e,u,o,i));case"[object Symbol]":if(vo)return vo.call(t)==vo.call(n)}return false}function Cr(t){for(var n=t.name+"",r=co[n],e=wu.call(co,n)?r.length:0;e--;){var u=r[e],o=u.func;if(null==o||o==t)return u.name}return n}function Mr(){var t=jt.iteratee||lu,t=t===lu?An:t;
+return arguments.length?t(arguments[0],arguments[1]):t}function Ur(t){t=ru(t);for(var n=t.length;n--;){var r=t[n][1];t[n][2]=r===r&&!ze(r)}return t}function zr(t,n){var r=t[n];return $e(r)?r:N}function Dr(t){return(wu.call(jt,"placeholder")?jt:t).placeholder}function $r(t){return Mu(Object(t))}function Fr(t){return ku.call(t)}function Nr(t,n,r){n=Yr(n,t)?[n]:nr(n);for(var e,u=-1,o=n.length;++u<o;){var i=ee(n[u]);if(!(e=null!=t&&r(t,i)))break;t=t[i]}return e?e:(o=t?t.length:0,!!o&&Ue(o)&&Gr(i,o)&&(li(t)||Ze(t)||Re(t)));
+}function Pr(t){var n=t.length,r=t.constructor(n);return n&&"string"==typeof t[0]&&wu.call(t,"index")&&(r.index=t.index,r.input=t.input),r}function Zr(t){return typeof t.constructor!="function"||Xr(t)?{}:en(Zu(Object(t)))}function Tr(r,e,u,o){var i=r.constructor;switch(e){case"[object ArrayBuffer]":return ur(r);case"[object Boolean]":case"[object Date]":return new i(+r);case"[object DataView]":return e=o?ur(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.byteLength);case"[object Float32Array]":
+case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return e=o?ur(r.buffer):r.buffer,new r.constructor(e,r.byteOffset,r.length);case"[object Map]":return e=o?u(M(r),true):M(r),s(e,t,new r.constructor);case"[object Number]":case"[object String]":return new i(r);case"[object RegExp]":return e=new r.constructor(r.source,st.exec(r)),e.lastIndex=r.lastIndex,
+e;case"[object Set]":return e=o?u(z(r),true):z(r),s(e,n,new r.constructor);case"[object Symbol]":return vo?Object(vo.call(r)):{}}}function qr(t){var n=t?t.length:N;return Ue(n)&&(li(t)||Ze(t)||Re(t))?m(n,String):null}function Vr(t){return Be(t)&&(li(t)||Re(t))}function Kr(t){return li(t)&&!(2==t.length&&!Ce(t[0]))}function Gr(t,n){return n=null==n?9007199254740991:n,!!n&&(typeof t=="number"||dt.test(t))&&t>-1&&0==t%1&&n>t}function Jr(t,n,r){if(!ze(r))return false;var e=typeof n;return("number"==e?We(r)&&Gr(n,r.length):"string"==e&&n in r)?Se(r[n],t):false;
+}function Yr(t,n){if(li(t))return false;var r=typeof t;return"number"==r||"symbol"==r||"boolean"==r||null==t||Te(t)?true:nt.test(t)||!tt.test(t)||null!=n&&t in Object(n)}function Hr(t){var n=typeof t;return"string"==n||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==t:null===t}function Qr(t){var n=Cr(t),r=jt[n];return typeof r=="function"&&n in Lt.prototype?t===r?true:(n=Ao(r),!!n&&t===n[0]):false}function Xr(t){var n=t&&t.constructor;return t===(typeof n=="function"&&n.prototype||xu)}function te(t,n){return function(r){
+return null==r?false:r[t]===n&&(n!==N||t in Object(r))}}function ne(t,n,r,e,u,o){return ze(t)&&ze(n)&&Rn(t,n,N,ne,o.set(n,t)),t}function re(t,n){return 1==n.length?t:_n(t,Pn(n,0,-1))}function ee(t){if(typeof t=="string"||Te(t))return t;var n=t+"";return"0"==n&&1/t==-P?"-0":n}function ue(t){if(null!=t){try{return mu.call(t)}catch(n){}return t+""}return""}function oe(t){if(t instanceof Lt)return t.clone();var n=new wt(t.__wrapped__,t.__chain__);return n.__actions__=cr(t.__actions__),n.__index__=t.__index__,
+n.__values__=t.__values__,n}function ie(t,n,r){var e=t?t.length:0;return e?(n=r||n===N?1:Ke(n),Pn(t,0>n?0:n,e)):[]}function fe(t,n,r){var e=t?t.length:0;return e?(n=r||n===N?1:Ke(n),n=e-n,Pn(t,0,0>n?0:n)):[]}function ce(t){return t&&t.length?t[0]:N}function ae(t){var n=t?t.length:0;return n?t[n-1]:N}function le(t,n){return t&&t.length&&n&&n.length?zn(t,n):t}function se(t){return t?Qu.call(t):t}function he(t){if(!t||!t.length)return[];var n=0;return t=i(t,function(t){return Be(t)?(n=Ku(t.length,n),
+!0):void 0}),m(n,function(n){return a(t,Mn(n))})}function pe(t,n){if(!t||!t.length)return[];var e=he(t);return null==n?e:a(e,function(t){return r(n,N,t)})}function _e(t){return t=jt(t),t.__chain__=true,t}function ve(t,n){return n(t)}function ge(){return this}function de(t,n){return typeof n=="function"&&li(t)?u(t,n):yo(t,Mr(n))}function ye(t,n){var r;if(typeof n=="function"&&li(t)){for(r=t.length;r--&&false!==n(t[r],r,t););r=t}else r=bo(t,Mr(n));return r}function be(t,n){return(li(t)?a:En)(t,Mr(n,3))}function xe(t,n,r){
+var e=-1,u=Ve(t),o=u.length,i=o-1;for(n=(r?Jr(t,n,r):n===N)?1:tn(Ke(n),0,o);++e<n;)t=$n(e,i),r=u[t],u[t]=u[e],u[e]=r;return u.length=n,u}function je(t,n,r){return n=r?N:n,n=t&&null==n?t.length:n,Wr(t,128,N,N,N,N,n)}function me(t,n){var r;if(typeof n!="function")throw new yu("Expected a function");return t=Ke(t),function(){return 0<--t&&(r=n.apply(this,arguments)),1>=t&&(n=N),r}}function we(t,n,r){return n=r?N:n,t=Wr(t,8,N,N,N,N,N,n),t.placeholder=we.placeholder,t}function Ae(t,n,r){return n=r?N:n,
+t=Wr(t,16,N,N,N,N,N,n),t.placeholder=Ae.placeholder,t}function Oe(t,n,r){function e(n){var r=c,e=a;return c=a=N,_=n,s=t.apply(e,r)}function u(t){var r=t-p;return t-=_,!p||r>=n||0>r||g&&t>=l}function o(){var t=Xo();if(u(t))return i(t);var r;r=t-_,t=n-(t-p),r=g?Gu(t,l-r):t,h=$u(o,r)}function i(t){return Lu(h),h=N,d&&c?e(t):(c=a=N,s)}function f(){var t=Xo(),r=u(t);if(c=arguments,a=this,p=t,r){if(h===N)return _=t=p,h=$u(o,n),v?e(t):s;if(g)return Lu(h),h=$u(o,n),e(p)}return h===N&&(h=$u(o,n)),s}var c,a,l,s,h,p=0,_=0,v=false,g=false,d=true;
+if(typeof t!="function")throw new yu("Expected a function");return n=Je(n)||0,ze(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Ku(Je(r.maxWait)||0,n):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==N&&Lu(h),p=_=0,c=a=h=N},f.flush=function(){return h===N?s:i(Xo())},f}function ke(t,n){function r(){var e=arguments,u=n?n.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=t.apply(this,e),r.cache=o.set(u,e),e)}if(typeof t!="function"||n&&typeof n!="function")throw new yu("Expected a function");
+return r.cache=new(ke.Cache||Mt),r}function Ee(t,n){if(typeof t!="function")throw new yu("Expected a function");return n=Ku(n===N?t.length-1:Ke(n),0),function(){for(var e=arguments,u=-1,o=Ku(e.length-n,0),i=Array(o);++u<o;)i[u]=e[n+u];switch(n){case 0:return t.call(this,i);case 1:return t.call(this,e[0],i);case 2:return t.call(this,e[0],e[1],i)}for(o=Array(n+1),u=-1;++u<n;)o[u]=e[u];return o[n]=i,r(t,this,o)}}function Ie(){if(!arguments.length)return[];var t=arguments[0];return li(t)?t:[t]}function Se(t,n){
+return t===n||t!==t&&n!==n}function Re(t){return Be(t)&&wu.call(t,"callee")&&(!Du.call(t,"callee")||"[object Arguments]"==ku.call(t))}function We(t){return null!=t&&Ue(Oo(t))&&!Ce(t)}function Be(t){return De(t)&&We(t)}function Le(t){return De(t)?"[object Error]"==ku.call(t)||typeof t.message=="string"&&typeof t.name=="string":false}function Ce(t){return t=ze(t)?ku.call(t):"","[object Function]"==t||"[object GeneratorFunction]"==t}function Me(t){return typeof t=="number"&&t==Ke(t)}function Ue(t){return typeof t=="number"&&t>-1&&0==t%1&&9007199254740991>=t;
+}function ze(t){var n=typeof t;return!!t&&("object"==n||"function"==n)}function De(t){return!!t&&typeof t=="object"}function $e(t){return ze(t)?(Ce(t)||L(t)?Iu:vt).test(ue(t)):false}function Fe(t){return typeof t=="number"||De(t)&&"[object Number]"==ku.call(t)}function Ne(t){return!De(t)||"[object Object]"!=ku.call(t)||L(t)?false:(t=Zu(Object(t)),null===t?true:(t=wu.call(t,"constructor")&&t.constructor,typeof t=="function"&&t instanceof t&&mu.call(t)==Ou))}function Pe(t){return ze(t)&&"[object RegExp]"==ku.call(t);
+}function Ze(t){return typeof t=="string"||!li(t)&&De(t)&&"[object String]"==ku.call(t)}function Te(t){return typeof t=="symbol"||De(t)&&"[object Symbol]"==ku.call(t)}function qe(t){return De(t)&&Ue(t.length)&&!!Wt[ku.call(t)]}function Ve(t){if(!t)return[];if(We(t))return Ze(t)?t.match(kt):cr(t);if(Uu&&t[Uu])return C(t[Uu]());var n=Fr(t);return("[object Map]"==n?M:"[object Set]"==n?z:uu)(t)}function Ke(t){if(!t)return 0===t?t:0;if(t=Je(t),t===P||t===-P)return 1.7976931348623157e308*(0>t?-1:1);var n=t%1;
+return t===t?n?t-n:t:0}function Ge(t){return t?tn(Ke(t),0,4294967295):0}function Je(t){if(typeof t=="number")return t;if(Te(t))return Z;if(ze(t)&&(t=Ce(t.valueOf)?t.valueOf():t,t=ze(t)?t+"":t),typeof t!="string")return 0===t?t:+t;t=t.replace(ot,"");var n=_t.test(t);return n||gt.test(t)?$t(t.slice(2),n?2:8):pt.test(t)?Z:+t}function Ye(t){return ar(t,nu(t))}function He(t){return null==t?"":Gn(t)}function Qe(t,n,r){return t=null==t?N:_n(t,n),t===N?r:t}function Xe(t,n){return null!=t&&Nr(t,n,yn)}function tu(t){
+var n=Xr(t);if(!n&&!We(t))return Vu(Object(t));var r,e=qr(t),u=!!e,e=e||[],o=e.length;for(r in t)!dn(t,r)||u&&("length"==r||Gr(r,o))||n&&"constructor"==r||e.push(r);return e}function nu(t){for(var n=-1,r=Xr(t),e=On(t),u=e.length,o=qr(t),i=!!o,o=o||[],f=o.length;++n<u;){var c=e[n];i&&("length"==c||Gr(c,f))||"constructor"==c&&(r||!wu.call(t,c))||o.push(c)}return o}function ru(t){return w(t,tu(t))}function eu(t){return w(t,nu(t))}function uu(t){return t?O(t,tu(t)):[]}function ou(t){return Mi(He(t).toLowerCase());
+}function iu(t){return(t=He(t))&&t.replace(yt,S).replace(Ot,"")}function fu(t,n,r){return t=He(t),n=r?N:n,n===N&&(n=St.test(t)?Et:ct),t.match(n)||[]}function cu(t){return function(){return t}}function au(t){return t}function lu(t){return An(typeof t=="function"?t:nn(t,true))}function su(t,n,r){var e=tu(n),o=pn(n,e);null!=r||ze(n)&&(o.length||!e.length)||(r=n,n=t,t=this,o=pn(n,tu(n)));var i=!(ze(r)&&"chain"in r&&!r.chain),f=Ce(t);return u(o,function(r){var e=n[r];t[r]=e,f&&(t.prototype[r]=function(){
+var n=this.__chain__;if(i||n){var r=t(this.__wrapped__);return(r.__actions__=cr(this.__actions__)).push({func:e,args:arguments,thisArg:t}),r.__chain__=n,r}return e.apply(t,l([this.value()],arguments))})}),t}function hu(){}function pu(t){return Yr(t)?Mn(ee(t)):Un(t)}I=I?Kt.defaults({},I,Kt.pick(Vt,Rt)):Vt;var _u=I.Date,vu=I.Error,gu=I.Math,du=I.RegExp,yu=I.TypeError,bu=I.Array.prototype,xu=I.Object.prototype,ju=I.String.prototype,mu=I.Function.prototype.toString,wu=xu.hasOwnProperty,Au=0,Ou=mu.call(Object),ku=xu.toString,Eu=Vt._,Iu=du("^"+mu.call(wu).replace(et,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),Su=Pt?I.Buffer:N,Ru=I.Reflect,Wu=I.Symbol,Bu=I.Uint8Array,Lu=I.clearTimeout,Cu=Ru?Ru.f:N,Mu=Object.getOwnPropertySymbols,Uu=typeof(Uu=Wu&&Wu.iterator)=="symbol"?Uu:N,zu=Object.create,Du=xu.propertyIsEnumerable,$u=I.setTimeout,Fu=bu.splice,Nu=gu.ceil,Pu=gu.floor,Zu=Object.getPrototypeOf,Tu=I.isFinite,qu=bu.join,Vu=Object.keys,Ku=gu.max,Gu=gu.min,Ju=I.parseInt,Yu=gu.random,Hu=ju.replace,Qu=bu.reverse,Xu=ju.split,to=zr(I,"DataView"),no=zr(I,"Map"),ro=zr(I,"Promise"),eo=zr(I,"Set"),uo=zr(I,"WeakMap"),oo=zr(Object,"create"),io=uo&&new uo,fo=!Du.call({
+valueOf:1},"valueOf"),co={},ao=ue(to),lo=ue(no),so=ue(ro),ho=ue(eo),po=ue(uo),_o=Wu?Wu.prototype:N,vo=_o?_o.valueOf:N,go=_o?_o.toString:N;jt.templateSettings={escape:H,evaluate:Q,interpolate:X,variable:"",imports:{_:jt}},jt.prototype=mt.prototype,jt.prototype.constructor=jt,wt.prototype=en(mt.prototype),wt.prototype.constructor=wt,Lt.prototype=en(mt.prototype),Lt.prototype.constructor=Lt,Ct.prototype=oo?oo(null):xu,Mt.prototype.clear=function(){this.__data__={hash:new Ct,map:no?new no:[],string:new Ct
+}},Mt.prototype["delete"]=function(t){var n=this.__data__;return Hr(t)?(n=typeof t=="string"?n.string:n.hash,t=(oo?n[t]!==N:wu.call(n,t))&&delete n[t]):t=no?n.map["delete"](t):Nt(n.map,t),t},Mt.prototype.get=function(t){var n=this.__data__;return Hr(t)?(n=typeof t=="string"?n.string:n.hash,oo?(t=n[t],t="__lodash_hash_undefined__"===t?N:t):t=wu.call(n,t)?n[t]:N):t=no?n.map.get(t):Zt(n.map,t),t},Mt.prototype.has=function(t){var n=this.__data__;return Hr(t)?(n=typeof t=="string"?n.string:n.hash,t=oo?n[t]!==N:wu.call(n,t)):t=no?n.map.has(t):-1<Tt(n.map,t),
+t},Mt.prototype.set=function(t,n){var r=this.__data__;return Hr(t)?(typeof t=="string"?r.string:r.hash)[t]=oo&&n===N?"__lodash_hash_undefined__":n:no?r.map.set(t,n):qt(r.map,t,n),this},Ut.prototype.push=function(t){var n=this.__data__;Hr(t)?(n=n.__data__,(typeof t=="string"?n.string:n.hash)[t]="__lodash_hash_undefined__"):n.set(t,"__lodash_hash_undefined__")},Ft.prototype.clear=function(){this.__data__={array:[],map:null}},Ft.prototype["delete"]=function(t){var n=this.__data__,r=n.array;return r?Nt(r,t):n.map["delete"](t);
+},Ft.prototype.get=function(t){var n=this.__data__,r=n.array;return r?Zt(r,t):n.map.get(t)},Ft.prototype.has=function(t){var n=this.__data__,r=n.array;return r?-1<Tt(r,t):n.map.has(t)},Ft.prototype.set=function(t,n){var r=this.__data__,e=r.array;return e&&(199>e.length?qt(e,t,n):(r.array=null,r.map=new Mt(e))),(r=r.map)&&r.set(t,n),this};var yo=pr(sn),bo=pr(hn,true),xo=_r(),jo=_r(true);Cu&&!Du.call({valueOf:1},"valueOf")&&(On=function(t){return C(Cu(t))});var mo=io?function(t,n){return io.set(t,n),t}:au,wo=eo&&1/z(new eo([,-0]))[1]==P?function(t){
+return new eo(t)}:hu,Ao=io?function(t){return io.get(t)}:hu,Oo=Mn("length");Mu||($r=function(){return[]});var ko=Mu?function(t){for(var n=[];t;)l(n,$r(t)),t=Zu(Object(t));return n}:$r;(to&&"[object DataView]"!=Fr(new to(new ArrayBuffer(1)))||no&&"[object Map]"!=Fr(new no)||ro&&"[object Promise]"!=Fr(ro.resolve())||eo&&"[object Set]"!=Fr(new eo)||uo&&"[object WeakMap]"!=Fr(new uo))&&(Fr=function(t){var n=ku.call(t);if(t=(t="[object Object]"==n?t.constructor:N)?ue(t):N)switch(t){case ao:return"[object DataView]";
+case lo:return"[object Map]";case so:return"[object Promise]";case ho:return"[object Set]";case po:return"[object WeakMap]"}return n});var Eo=function(){var t=0,n=0;return function(r,e){var u=Xo(),o=16-(u-n);if(n=u,o>0){if(150<=++t)return r}else t=0;return mo(r,e)}}(),Io=ke(function(t){var n=[];return He(t).replace(rt,function(t,r,e,u){n.push(e?u.replace(at,"$1"):r||t)}),n}),So=Ee(function(t,n){return Be(t)?on(t,ln(n,1,Be,true)):[]}),Ro=Ee(function(t,n){var r=ae(n);return Be(r)&&(r=N),Be(t)?on(t,ln(n,1,Be,true),Mr(r)):[];
+}),Wo=Ee(function(t,n){var r=ae(n);return Be(r)&&(r=N),Be(t)?on(t,ln(n,1,Be,true),N,r):[]}),Bo=Ee(function(t){var n=a(t,tr);return n.length&&n[0]===t[0]?bn(n):[]}),Lo=Ee(function(t){var n=ae(t),r=a(t,tr);return n===ae(r)?n=N:r.pop(),r.length&&r[0]===t[0]?bn(r,Mr(n)):[]}),Co=Ee(function(t){var n=ae(t),r=a(t,tr);return n===ae(r)?n=N:r.pop(),r.length&&r[0]===t[0]?bn(r,N,n):[]}),Mo=Ee(le),Uo=Ee(function(t,n){n=ln(n,1);var r=t?t.length:0,e=Xt(t,n);return Dn(t,a(n,function(t){return Gr(t,r)?+t:t}).sort(or)),
+e}),zo=Ee(function(t){return Jn(ln(t,1,Be,true))}),Do=Ee(function(t){var n=ae(t);return Be(n)&&(n=N),Jn(ln(t,1,Be,true),Mr(n))}),$o=Ee(function(t){var n=ae(t);return Be(n)&&(n=N),Jn(ln(t,1,Be,true),N,n)}),Fo=Ee(function(t,n){return Be(t)?on(t,n):[]}),No=Ee(function(t){return Qn(i(t,Be))}),Po=Ee(function(t){var n=ae(t);return Be(n)&&(n=N),Qn(i(t,Be),Mr(n))}),Zo=Ee(function(t){var n=ae(t);return Be(n)&&(n=N),Qn(i(t,Be),N,n)}),To=Ee(he),qo=Ee(function(t){var n=t.length,n=n>1?t[n-1]:N,n=typeof n=="function"?(t.pop(),
+n):N;return pe(t,n)}),Vo=Ee(function(t){function n(n){return Xt(n,t)}t=ln(t,1);var r=t.length,e=r?t[0]:0,u=this.__wrapped__;return!(r>1||this.__actions__.length)&&u instanceof Lt&&Gr(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:ve,args:[n],thisArg:N}),new wt(u,this.__chain__).thru(function(t){return r&&!t.length&&t.push(N),t})):this.thru(n)}),Ko=sr(function(t,n,r){wu.call(t,r)?++t[r]:t[r]=1}),Go=sr(function(t,n,r){wu.call(t,r)?t[r].push(n):t[r]=[n]}),Jo=Ee(function(t,n,e){var u=-1,o=typeof n=="function",i=Yr(n),f=We(t)?Array(t.length):[];
+return yo(t,function(t){var c=o?n:i&&null!=t?t[n]:N;f[++u]=c?r(c,t,e):jn(t,n,e)}),f}),Yo=sr(function(t,n,r){t[r]=n}),Ho=sr(function(t,n,r){t[r?0:1].push(n)},function(){return[[],[]]}),Qo=Ee(function(t,n){if(null==t)return[];var r=n.length;return r>1&&Jr(t,n[0],n[1])?n=[]:r>2&&Jr(n[0],n[1],n[2])&&(n=[n[0]]),n=1==n.length&&li(n[0])?n[0]:ln(n,1,Kr),Bn(t,n,[])}),Xo=_u.now,ti=Ee(function(t,n,r){var e=1;if(r.length)var u=U(r,Dr(ti)),e=32|e;return Wr(t,e,n,r,u)}),ni=Ee(function(t,n,r){var e=3;if(r.length)var u=U(r,Dr(ni)),e=32|e;
+return Wr(n,e,t,r,u)}),ri=Ee(function(t,n){return un(t,1,n)}),ei=Ee(function(t,n,r){return un(t,Je(n)||0,r)});ke.Cache=Mt;var ui=Ee(function(t,n){n=1==n.length&&li(n[0])?a(n[0],A(Mr())):a(ln(n,1,Kr),A(Mr()));var e=n.length;return Ee(function(u){for(var o=-1,i=Gu(u.length,e);++o<i;)u[o]=n[o].call(this,u[o]);return r(t,this,u)})}),oi=Ee(function(t,n){var r=U(n,Dr(oi));return Wr(t,32,N,n,r)}),ii=Ee(function(t,n){var r=U(n,Dr(ii));return Wr(t,64,N,n,r)}),fi=Ee(function(t,n){return Wr(t,256,N,N,N,ln(n,1));
+}),ci=Ir(gn),ai=Ir(function(t,n){return t>=n}),li=Array.isArray,si=Su?function(t){return t instanceof Su}:cu(false),hi=Ir(kn),pi=Ir(function(t,n){return n>=t}),_i=hr(function(t,n){if(fo||Xr(n)||We(n))ar(n,tu(n),t);else for(var r in n)wu.call(n,r)&&Yt(t,r,n[r])}),vi=hr(function(t,n){if(fo||Xr(n)||We(n))ar(n,nu(n),t);else for(var r in n)Yt(t,r,n[r])}),gi=hr(function(t,n,r,e){ar(n,nu(n),t,e)}),di=hr(function(t,n,r,e){ar(n,tu(n),t,e)}),yi=Ee(function(t,n){return Xt(t,ln(n,1))}),bi=Ee(function(t){return t.push(N,Gt),
+r(gi,N,t)}),xi=Ee(function(t){return t.push(N,ne),r(Oi,N,t)}),ji=mr(function(t,n,r){t[n]=r},cu(au)),mi=mr(function(t,n,r){wu.call(t,n)?t[n].push(r):t[n]=[r]},Mr),wi=Ee(jn),Ai=hr(function(t,n,r){Rn(t,n,r)}),Oi=hr(function(t,n,r,e){Rn(t,n,r,e)}),ki=Ee(function(t,n){return null==t?{}:(n=a(ln(n,1),ee),Ln(t,on(vn(t,nu,ko),n)))}),Ei=Ee(function(t,n){return null==t?{}:Ln(t,a(ln(n,1),ee))}),Ii=dr(function(t,n,r){return n=n.toLowerCase(),t+(r?ou(n):n)}),Si=dr(function(t,n,r){return t+(r?"-":"")+n.toLowerCase();
+}),Ri=dr(function(t,n,r){return t+(r?" ":"")+n.toLowerCase()}),Wi=gr("toLowerCase"),Bi=dr(function(t,n,r){return t+(r?"_":"")+n.toLowerCase()}),Li=dr(function(t,n,r){return t+(r?" ":"")+Mi(n)}),Ci=dr(function(t,n,r){return t+(r?" ":"")+n.toUpperCase()}),Mi=gr("toUpperCase"),Ui=Ee(function(t,n){try{return r(t,N,n)}catch(e){return Le(e)?e:new vu(e)}}),zi=Ee(function(t,n){return u(ln(n,1),function(n){n=ee(n),t[n]=ti(t[n],t)}),t}),Di=xr(),$i=xr(true),Fi=Ee(function(t,n){return function(r){return jn(r,t,n);
+}}),Ni=Ee(function(t,n){return function(r){return jn(t,r,n)}}),Pi=Ar(a),Zi=Ar(o),Ti=Ar(p),qi=Er(),Vi=Er(true),Ki=wr(function(t,n){return t+n}),Gi=Rr("ceil"),Ji=wr(function(t,n){return t/n}),Yi=Rr("floor"),Hi=wr(function(t,n){return t*n}),Qi=Rr("round"),Xi=wr(function(t,n){return t-n});return jt.after=function(t,n){if(typeof n!="function")throw new yu("Expected a function");return t=Ke(t),function(){return 1>--t?n.apply(this,arguments):void 0}},jt.ary=je,jt.assign=_i,jt.assignIn=vi,jt.assignInWith=gi,
+jt.assignWith=di,jt.at=yi,jt.before=me,jt.bind=ti,jt.bindAll=zi,jt.bindKey=ni,jt.castArray=Ie,jt.chain=_e,jt.chunk=function(t,n,r){if(n=(r?Jr(t,n,r):n===N)?1:Ku(Ke(n),0),r=t?t.length:0,!r||1>n)return[];for(var e=0,u=0,o=Array(Nu(r/n));r>e;)o[u++]=Pn(t,e,e+=n);return o},jt.compact=function(t){for(var n=-1,r=t?t.length:0,e=0,u=[];++n<r;){var o=t[n];o&&(u[e++]=o)}return u},jt.concat=function(){var t=arguments.length,n=Ie(arguments[0]);if(2>t)return t?cr(n):[];for(var r=Array(t-1);t--;)r[t-1]=arguments[t];
+for(var t=ln(r,1),r=-1,e=n.length,u=-1,o=t.length,i=Array(e+o);++r<e;)i[r]=n[r];for(;++u<o;)i[r++]=t[u];return i},jt.cond=function(t){var n=t?t.length:0,e=Mr();return t=n?a(t,function(t){if("function"!=typeof t[1])throw new yu("Expected a function");return[e(t[0]),t[1]]}):[],Ee(function(e){for(var u=-1;++u<n;){var o=t[u];if(r(o[0],this,e))return r(o[1],this,e)}})},jt.conforms=function(t){return rn(nn(t,true))},jt.constant=cu,jt.countBy=Ko,jt.create=function(t,n){var r=en(t);return n?Qt(r,n):r},jt.curry=we,
+jt.curryRight=Ae,jt.debounce=Oe,jt.defaults=bi,jt.defaultsDeep=xi,jt.defer=ri,jt.delay=ei,jt.difference=So,jt.differenceBy=Ro,jt.differenceWith=Wo,jt.drop=ie,jt.dropRight=fe,jt.dropRightWhile=function(t,n){return t&&t.length?Yn(t,Mr(n,3),true,true):[]},jt.dropWhile=function(t,n){return t&&t.length?Yn(t,Mr(n,3),true):[]},jt.fill=function(t,n,r,e){var u=t?t.length:0;if(!u)return[];for(r&&typeof r!="number"&&Jr(t,n,r)&&(r=0,e=u),u=t.length,r=Ke(r),0>r&&(r=-r>u?0:u+r),e=e===N||e>u?u:Ke(e),0>e&&(e+=u),e=r>e?0:Ge(e);e>r;)t[r++]=n;
+return t},jt.filter=function(t,n){return(li(t)?i:an)(t,Mr(n,3))},jt.flatMap=function(t,n){return ln(be(t,n),1)},jt.flatMapDeep=function(t,n){return ln(be(t,n),P)},jt.flatMapDepth=function(t,n,r){return r=r===N?1:Ke(r),ln(be(t,n),r)},jt.flatten=function(t){return t&&t.length?ln(t,1):[]},jt.flattenDeep=function(t){return t&&t.length?ln(t,P):[]},jt.flattenDepth=function(t,n){return t&&t.length?(n=n===N?1:Ke(n),ln(t,n)):[]},jt.flip=function(t){return Wr(t,512)},jt.flow=Di,jt.flowRight=$i,jt.fromPairs=function(t){
+for(var n=-1,r=t?t.length:0,e={};++n<r;){var u=t[n];e[u[0]]=u[1]}return e},jt.functions=function(t){return null==t?[]:pn(t,tu(t))},jt.functionsIn=function(t){return null==t?[]:pn(t,nu(t))},jt.groupBy=Go,jt.initial=function(t){return fe(t,1)},jt.intersection=Bo,jt.intersectionBy=Lo,jt.intersectionWith=Co,jt.invert=ji,jt.invertBy=mi,jt.invokeMap=Jo,jt.iteratee=lu,jt.keyBy=Yo,jt.keys=tu,jt.keysIn=nu,jt.map=be,jt.mapKeys=function(t,n){var r={};return n=Mr(n,3),sn(t,function(t,e,u){r[n(t,e,u)]=t}),r},
+jt.mapValues=function(t,n){var r={};return n=Mr(n,3),sn(t,function(t,e,u){r[e]=n(t,e,u)}),r},jt.matches=function(t){return In(nn(t,true))},jt.matchesProperty=function(t,n){return Sn(t,nn(n,true))},jt.memoize=ke,jt.merge=Ai,jt.mergeWith=Oi,jt.method=Fi,jt.methodOf=Ni,jt.mixin=su,jt.negate=function(t){if(typeof t!="function")throw new yu("Expected a function");return function(){return!t.apply(this,arguments)}},jt.nthArg=function(t){return t=Ke(t),Ee(function(n){return Wn(n,t)})},jt.omit=ki,jt.omitBy=function(t,n){
+return n=Mr(n),Cn(t,function(t,r){return!n(t,r)})},jt.once=function(t){return me(2,t)},jt.orderBy=function(t,n,r,e){return null==t?[]:(li(n)||(n=null==n?[]:[n]),r=e?N:r,li(r)||(r=null==r?[]:[r]),Bn(t,n,r))},jt.over=Pi,jt.overArgs=ui,jt.overEvery=Zi,jt.overSome=Ti,jt.partial=oi,jt.partialRight=ii,jt.partition=Ho,jt.pick=Ei,jt.pickBy=function(t,n){return null==t?{}:Cn(t,Mr(n))},jt.property=pu,jt.propertyOf=function(t){return function(n){return null==t?N:_n(t,n)}},jt.pull=Mo,jt.pullAll=le,jt.pullAllBy=function(t,n,r){
+return t&&t.length&&n&&n.length?zn(t,n,Mr(r)):t},jt.pullAllWith=function(t,n,r){return t&&t.length&&n&&n.length?zn(t,n,N,r):t},jt.pullAt=Uo,jt.range=qi,jt.rangeRight=Vi,jt.rearg=fi,jt.reject=function(t,n){var r=li(t)?i:an;return n=Mr(n,3),r(t,function(t,r,e){return!n(t,r,e)})},jt.remove=function(t,n){var r=[];if(!t||!t.length)return r;var e=-1,u=[],o=t.length;for(n=Mr(n,3);++e<o;){var i=t[e];n(i,e,t)&&(r.push(i),u.push(e))}return Dn(t,u),r},jt.rest=Ee,jt.reverse=se,jt.sampleSize=xe,jt.set=function(t,n,r){
+return null==t?t:Nn(t,n,r)},jt.setWith=function(t,n,r,e){return e=typeof e=="function"?e:N,null==t?t:Nn(t,n,r,e)},jt.shuffle=function(t){return xe(t,4294967295)},jt.slice=function(t,n,r){var e=t?t.length:0;return e?(r&&typeof r!="number"&&Jr(t,n,r)?(n=0,r=e):(n=null==n?0:Ke(n),r=r===N?e:Ke(r)),Pn(t,n,r)):[]},jt.sortBy=Qo,jt.sortedUniq=function(t){return t&&t.length?Vn(t):[]},jt.sortedUniqBy=function(t,n){return t&&t.length?Vn(t,Mr(n)):[]},jt.split=function(t,n,r){return r&&typeof r!="number"&&Jr(t,n,r)&&(n=r=N),
+r=r===N?4294967295:r>>>0,r?(t=He(t))&&(typeof n=="string"||null!=n&&!Pe(n))&&(n=Gn(n),""==n&&It.test(t))?rr(t.match(kt),0,r):Xu.call(t,n,r):[]},jt.spread=function(t,n){if(typeof t!="function")throw new yu("Expected a function");return n=n===N?0:Ku(Ke(n),0),Ee(function(e){var u=e[n];return e=rr(e,0,n),u&&l(e,u),r(t,this,e)})},jt.tail=function(t){return ie(t,1)},jt.take=function(t,n,r){return t&&t.length?(n=r||n===N?1:Ke(n),Pn(t,0,0>n?0:n)):[]},jt.takeRight=function(t,n,r){var e=t?t.length:0;return e?(n=r||n===N?1:Ke(n),
+n=e-n,Pn(t,0>n?0:n,e)):[]},jt.takeRightWhile=function(t,n){return t&&t.length?Yn(t,Mr(n,3),false,true):[]},jt.takeWhile=function(t,n){return t&&t.length?Yn(t,Mr(n,3)):[]},jt.tap=function(t,n){return n(t),t},jt.throttle=function(t,n,r){var e=true,u=true;if(typeof t!="function")throw new yu("Expected a function");return ze(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Oe(t,n,{leading:e,maxWait:n,trailing:u})},jt.thru=ve,jt.toArray=Ve,jt.toPairs=ru,jt.toPairsIn=eu,jt.toPath=function(t){
+return li(t)?a(t,ee):Te(t)?[t]:cr(Io(t))},jt.toPlainObject=Ye,jt.transform=function(t,n,r){var e=li(t)||qe(t);if(n=Mr(n,4),null==r)if(e||ze(t)){var o=t.constructor;r=e?li(t)?new o:[]:Ce(o)?en(Zu(Object(t))):{}}else r={};return(e?u:sn)(t,function(t,e,u){return n(r,t,e,u)}),r},jt.unary=function(t){return je(t,1)},jt.union=zo,jt.unionBy=Do,jt.unionWith=$o,jt.uniq=function(t){return t&&t.length?Jn(t):[]},jt.uniqBy=function(t,n){return t&&t.length?Jn(t,Mr(n)):[]},jt.uniqWith=function(t,n){return t&&t.length?Jn(t,N,n):[];
+},jt.unset=function(t,n){var r;if(null==t)r=true;else{r=t;var e=n,e=Yr(e,r)?[e]:nr(e);r=re(r,e),e=ee(ae(e)),r=!(null!=r&&dn(r,e))||delete r[e]}return r},jt.unzip=he,jt.unzipWith=pe,jt.update=function(t,n,r){return null==t?t:Nn(t,n,(typeof r=="function"?r:au)(_n(t,n)),void 0)},jt.updateWith=function(t,n,r,e){return e=typeof e=="function"?e:N,null!=t&&(t=Nn(t,n,(typeof r=="function"?r:au)(_n(t,n)),e)),t},jt.values=uu,jt.valuesIn=function(t){return null==t?[]:O(t,nu(t))},jt.without=Fo,jt.words=fu,jt.wrap=function(t,n){
+return n=null==n?au:n,oi(n,t)},jt.xor=No,jt.xorBy=Po,jt.xorWith=Zo,jt.zip=To,jt.zipObject=function(t,n){return Xn(t||[],n||[],Yt)},jt.zipObjectDeep=function(t,n){return Xn(t||[],n||[],Nn)},jt.zipWith=qo,jt.entries=ru,jt.entriesIn=eu,jt.extend=vi,jt.extendWith=gi,su(jt,jt),jt.add=Ki,jt.attempt=Ui,jt.camelCase=Ii,jt.capitalize=ou,jt.ceil=Gi,jt.clamp=function(t,n,r){return r===N&&(r=n,n=N),r!==N&&(r=Je(r),r=r===r?r:0),n!==N&&(n=Je(n),n=n===n?n:0),tn(Je(t),n,r)},jt.clone=function(t){return nn(t,false,true);
+},jt.cloneDeep=function(t){return nn(t,true,true)},jt.cloneDeepWith=function(t,n){return nn(t,true,true,n)},jt.cloneWith=function(t,n){return nn(t,false,true,n)},jt.deburr=iu,jt.divide=Ji,jt.endsWith=function(t,n,r){t=He(t),n=Gn(n);var e=t.length;return r=r===N?e:tn(Ke(r),0,e),r-=n.length,r>=0&&t.indexOf(n,r)==r},jt.eq=Se,jt.escape=function(t){return(t=He(t))&&Y.test(t)?t.replace(G,R):t},jt.escapeRegExp=function(t){return(t=He(t))&&ut.test(t)?t.replace(et,"\\$&"):t},jt.every=function(t,n,r){var e=li(t)?o:fn;return r&&Jr(t,n,r)&&(n=N),
+e(t,Mr(n,3))},jt.find=function(t,n){if(n=Mr(n,3),li(t)){var r=v(t,n);return r>-1?t[r]:N}return _(t,n,yo)},jt.findIndex=function(t,n){return t&&t.length?v(t,Mr(n,3)):-1},jt.findKey=function(t,n){return _(t,Mr(n,3),sn,true)},jt.findLast=function(t,n){if(n=Mr(n,3),li(t)){var r=v(t,n,true);return r>-1?t[r]:N}return _(t,n,bo)},jt.findLastIndex=function(t,n){return t&&t.length?v(t,Mr(n,3),true):-1},jt.findLastKey=function(t,n){return _(t,Mr(n,3),hn,true)},jt.floor=Yi,jt.forEach=de,jt.forEachRight=ye,jt.forIn=function(t,n){
+return null==t?t:xo(t,Mr(n),nu)},jt.forInRight=function(t,n){return null==t?t:jo(t,Mr(n),nu)},jt.forOwn=function(t,n){return t&&sn(t,Mr(n))},jt.forOwnRight=function(t,n){return t&&hn(t,Mr(n))},jt.get=Qe,jt.gt=ci,jt.gte=ai,jt.has=function(t,n){return null!=t&&Nr(t,n,dn)},jt.hasIn=Xe,jt.head=ce,jt.identity=au,jt.includes=function(t,n,r,e){return t=We(t)?t:uu(t),r=r&&!e?Ke(r):0,e=t.length,0>r&&(r=Ku(e+r,0)),Ze(t)?e>=r&&-1<t.indexOf(n,r):!!e&&-1<g(t,n,r)},jt.indexOf=function(t,n,r){var e=t?t.length:0;
+return e?(r=Ke(r),0>r&&(r=Ku(e+r,0)),g(t,n,r)):-1},jt.inRange=function(t,n,r){return n=Je(n)||0,r===N?(r=n,n=0):r=Je(r)||0,t=Je(t),t>=Gu(n,r)&&t<Ku(n,r)},jt.invoke=wi,jt.isArguments=Re,jt.isArray=li,jt.isArrayBuffer=function(t){return De(t)&&"[object ArrayBuffer]"==ku.call(t)},jt.isArrayLike=We,jt.isArrayLikeObject=Be,jt.isBoolean=function(t){return true===t||false===t||De(t)&&"[object Boolean]"==ku.call(t)},jt.isBuffer=si,jt.isDate=function(t){return De(t)&&"[object Date]"==ku.call(t)},jt.isElement=function(t){
+return!!t&&1===t.nodeType&&De(t)&&!Ne(t)},jt.isEmpty=function(t){if(We(t)&&(li(t)||Ze(t)||Ce(t.splice)||Re(t)||si(t)))return!t.length;if(De(t)){var n=Fr(t);if("[object Map]"==n||"[object Set]"==n)return!t.size}for(var r in t)if(wu.call(t,r))return false;return!(fo&&tu(t).length)},jt.isEqual=function(t,n){return mn(t,n)},jt.isEqualWith=function(t,n,r){var e=(r=typeof r=="function"?r:N)?r(t,n):N;return e===N?mn(t,n,r):!!e},jt.isError=Le,jt.isFinite=function(t){return typeof t=="number"&&Tu(t)},jt.isFunction=Ce,
+jt.isInteger=Me,jt.isLength=Ue,jt.isMap=function(t){return De(t)&&"[object Map]"==Fr(t)},jt.isMatch=function(t,n){return t===n||wn(t,n,Ur(n))},jt.isMatchWith=function(t,n,r){return r=typeof r=="function"?r:N,wn(t,n,Ur(n),r)},jt.isNaN=function(t){return Fe(t)&&t!=+t},jt.isNative=$e,jt.isNil=function(t){return null==t},jt.isNull=function(t){return null===t},jt.isNumber=Fe,jt.isObject=ze,jt.isObjectLike=De,jt.isPlainObject=Ne,jt.isRegExp=Pe,jt.isSafeInteger=function(t){return Me(t)&&t>=-9007199254740991&&9007199254740991>=t;
+},jt.isSet=function(t){return De(t)&&"[object Set]"==Fr(t)},jt.isString=Ze,jt.isSymbol=Te,jt.isTypedArray=qe,jt.isUndefined=function(t){return t===N},jt.isWeakMap=function(t){return De(t)&&"[object WeakMap]"==Fr(t)},jt.isWeakSet=function(t){return De(t)&&"[object WeakSet]"==ku.call(t)},jt.join=function(t,n){return t?qu.call(t,n):""},jt.kebabCase=Si,jt.last=ae,jt.lastIndexOf=function(t,n,r){var e=t?t.length:0;if(!e)return-1;var u=e;if(r!==N&&(u=Ke(r),u=(0>u?Ku(e+u,0):Gu(u,e-1))+1),n!==n)return B(t,u,true);
+for(;u--;)if(t[u]===n)return u;return-1},jt.lowerCase=Ri,jt.lowerFirst=Wi,jt.lt=hi,jt.lte=pi,jt.max=function(t){return t&&t.length?cn(t,au,gn):N},jt.maxBy=function(t,n){return t&&t.length?cn(t,Mr(n),gn):N},jt.mean=function(t){return y(t,au)},jt.meanBy=function(t,n){return y(t,Mr(n))},jt.min=function(t){return t&&t.length?cn(t,au,kn):N},jt.minBy=function(t,n){return t&&t.length?cn(t,Mr(n),kn):N},jt.multiply=Hi,jt.nth=function(t,n){return t&&t.length?Wn(t,Ke(n)):N},jt.noConflict=function(){return Vt._===this&&(Vt._=Eu),
+this},jt.noop=hu,jt.now=Xo,jt.pad=function(t,n,r){t=He(t);var e=(n=Ke(n))?D(t):0;return!n||e>=n?t:(n=(n-e)/2,Or(Pu(n),r)+t+Or(Nu(n),r))},jt.padEnd=function(t,n,r){t=He(t);var e=(n=Ke(n))?D(t):0;return n&&n>e?t+Or(n-e,r):t},jt.padStart=function(t,n,r){t=He(t);var e=(n=Ke(n))?D(t):0;return n&&n>e?Or(n-e,r)+t:t},jt.parseInt=function(t,n,r){return r||null==n?n=0:n&&(n=+n),t=He(t).replace(ot,""),Ju(t,n||(ht.test(t)?16:10))},jt.random=function(t,n,r){if(r&&typeof r!="boolean"&&Jr(t,n,r)&&(n=r=N),r===N&&(typeof n=="boolean"?(r=n,
+n=N):typeof t=="boolean"&&(r=t,t=N)),t===N&&n===N?(t=0,n=1):(t=Je(t)||0,n===N?(n=t,t=0):n=Je(n)||0),t>n){var e=t;t=n,n=e}return r||t%1||n%1?(r=Yu(),Gu(t+r*(n-t+Dt("1e-"+((r+"").length-1))),n)):$n(t,n)},jt.reduce=function(t,n,r){var e=li(t)?s:b,u=3>arguments.length;return e(t,Mr(n,4),r,u,yo)},jt.reduceRight=function(t,n,r){var e=li(t)?h:b,u=3>arguments.length;return e(t,Mr(n,4),r,u,bo)},jt.repeat=function(t,n,r){return n=(r?Jr(t,n,r):n===N)?1:Ke(n),Fn(He(t),n)},jt.replace=function(){var t=arguments,n=He(t[0]);
+return 3>t.length?n:Hu.call(n,t[1],t[2])},jt.result=function(t,n,r){n=Yr(n,t)?[n]:nr(n);var e=-1,u=n.length;for(u||(t=N,u=1);++e<u;){var o=null==t?N:t[ee(n[e])];o===N&&(e=u,o=r),t=Ce(o)?o.call(t):o}return t},jt.round=Qi,jt.runInContext=F,jt.sample=function(t){t=We(t)?t:uu(t);var n=t.length;return n>0?t[$n(0,n-1)]:N},jt.size=function(t){if(null==t)return 0;if(We(t)){var n=t.length;return n&&Ze(t)?D(t):n}return De(t)&&(n=Fr(t),"[object Map]"==n||"[object Set]"==n)?t.size:tu(t).length},jt.snakeCase=Bi,
+jt.some=function(t,n,r){var e=li(t)?p:Zn;return r&&Jr(t,n,r)&&(n=N),e(t,Mr(n,3))},jt.sortedIndex=function(t,n){return Tn(t,n)},jt.sortedIndexBy=function(t,n,r){return qn(t,n,Mr(r))},jt.sortedIndexOf=function(t,n){var r=t?t.length:0;if(r){var e=Tn(t,n);if(r>e&&Se(t[e],n))return e}return-1},jt.sortedLastIndex=function(t,n){return Tn(t,n,true)},jt.sortedLastIndexBy=function(t,n,r){return qn(t,n,Mr(r),true)},jt.sortedLastIndexOf=function(t,n){if(t&&t.length){var r=Tn(t,n,true)-1;if(Se(t[r],n))return r}return-1;
+},jt.startCase=Li,jt.startsWith=function(t,n,r){return t=He(t),r=tn(Ke(r),0,t.length),t.lastIndexOf(Gn(n),r)==r},jt.subtract=Xi,jt.sum=function(t){return t&&t.length?j(t,au):0},jt.sumBy=function(t,n){return t&&t.length?j(t,Mr(n)):0},jt.template=function(t,n,r){var e=jt.templateSettings;r&&Jr(t,n,r)&&(n=N),t=He(t),n=gi({},n,e,Gt),r=gi({},n.imports,e.imports,Gt);var u,o,i=tu(r),f=O(r,i),c=0;r=n.interpolate||bt;var a="__p+='";r=du((n.escape||bt).source+"|"+r.source+"|"+(r===X?lt:bt).source+"|"+(n.evaluate||bt).source+"|$","g");
+var l="sourceURL"in n?"//# sourceURL="+n.sourceURL+"\n":"";if(t.replace(r,function(n,r,e,i,f,l){return e||(e=i),a+=t.slice(c,l).replace(xt,W),r&&(u=true,a+="'+__e("+r+")+'"),f&&(o=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+n.length,n}),a+="';",(n=n.variable)||(a="with(obj){"+a+"}"),a=(o?a.replace(T,""):a).replace(q,"$1").replace(V,"$1;"),a="function("+(n||"obj")+"){"+(n?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",
+n=Ui(function(){return Function(i,l+"return "+a).apply(N,f)}),n.source=a,Le(n))throw n;return n},jt.times=function(t,n){if(t=Ke(t),1>t||t>9007199254740991)return[];var r=4294967295,e=Gu(t,4294967295);for(n=Mr(n),t-=4294967295,e=m(e,n);++r<t;)n(r);return e},jt.toInteger=Ke,jt.toLength=Ge,jt.toLower=function(t){return He(t).toLowerCase()},jt.toNumber=Je,jt.toSafeInteger=function(t){return tn(Ke(t),-9007199254740991,9007199254740991)},jt.toString=He,jt.toUpper=function(t){return He(t).toUpperCase()},
+jt.trim=function(t,n,r){return(t=He(t))&&(r||n===N)?t.replace(ot,""):t&&(n=Gn(n))?(t=t.match(kt),n=n.match(kt),rr(t,k(t,n),E(t,n)+1).join("")):t},jt.trimEnd=function(t,n,r){return(t=He(t))&&(r||n===N)?t.replace(ft,""):t&&(n=Gn(n))?(t=t.match(kt),n=E(t,n.match(kt))+1,rr(t,0,n).join("")):t},jt.trimStart=function(t,n,r){return(t=He(t))&&(r||n===N)?t.replace(it,""):t&&(n=Gn(n))?(t=t.match(kt),n=k(t,n.match(kt)),rr(t,n).join("")):t},jt.truncate=function(t,n){var r=30,e="...";if(ze(n))var u="separator"in n?n.separator:u,r="length"in n?Ke(n.length):r,e="omission"in n?Gn(n.omission):e;
+t=He(t);var o=t.length;if(It.test(t))var i=t.match(kt),o=i.length;if(r>=o)return t;if(o=r-D(e),1>o)return e;if(r=i?rr(i,0,o).join(""):t.slice(0,o),u===N)return r+e;if(i&&(o+=r.length-o),Pe(u)){if(t.slice(o).search(u)){var f=r;for(u.global||(u=du(u.source,He(st.exec(u))+"g")),u.lastIndex=0;i=u.exec(f);)var c=i.index;r=r.slice(0,c===N?o:c)}}else t.indexOf(Gn(u),o)!=o&&(u=r.lastIndexOf(u),u>-1&&(r=r.slice(0,u)));return r+e},jt.unescape=function(t){return(t=He(t))&&J.test(t)?t.replace(K,$):t},jt.uniqueId=function(t){
+var n=++Au;return He(t)+n},jt.upperCase=Ci,jt.upperFirst=Mi,jt.each=de,jt.eachRight=ye,jt.first=ce,su(jt,function(){var t={};return sn(jt,function(n,r){wu.call(jt.prototype,r)||(t[r]=n)}),t}(),{chain:false}),jt.VERSION="4.11.2",u("bind bindKey curry curryRight partial partialRight".split(" "),function(t){jt[t].placeholder=jt}),u(["drop","take"],function(t,n){Lt.prototype[t]=function(r){var e=this.__filtered__;if(e&&!n)return new Lt(this);r=r===N?1:Ku(Ke(r),0);var u=this.clone();return e?u.__takeCount__=Gu(r,u.__takeCount__):u.__views__.push({
+size:Gu(r,4294967295),type:t+(0>u.__dir__?"Right":"")}),u},Lt.prototype[t+"Right"]=function(n){return this.reverse()[t](n).reverse()}}),u(["filter","map","takeWhile"],function(t,n){var r=n+1,e=1==r||3==r;Lt.prototype[t]=function(t){var n=this.clone();return n.__iteratees__.push({iteratee:Mr(t,3),type:r}),n.__filtered__=n.__filtered__||e,n}}),u(["head","last"],function(t,n){var r="take"+(n?"Right":"");Lt.prototype[t]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(t,n){var r="drop"+(n?"":"Right");
+Lt.prototype[t]=function(){return this.__filtered__?new Lt(this):this[r](1)}}),Lt.prototype.compact=function(){return this.filter(au)},Lt.prototype.find=function(t){return this.filter(t).head()},Lt.prototype.findLast=function(t){return this.reverse().find(t)},Lt.prototype.invokeMap=Ee(function(t,n){return typeof t=="function"?new Lt(this):this.map(function(r){return jn(r,t,n)})}),Lt.prototype.reject=function(t){return t=Mr(t,3),this.filter(function(n){return!t(n)})},Lt.prototype.slice=function(t,n){
+t=Ke(t);var r=this;return r.__filtered__&&(t>0||0>n)?new Lt(r):(0>t?r=r.takeRight(-t):t&&(r=r.drop(t)),n!==N&&(n=Ke(n),r=0>n?r.dropRight(-n):r.take(n-t)),r)},Lt.prototype.takeRightWhile=function(t){return this.reverse().takeWhile(t).reverse()},Lt.prototype.toArray=function(){return this.take(4294967295)},sn(Lt.prototype,function(t,n){var r=/^(?:filter|find|map|reject)|While$/.test(n),e=/^(?:head|last)$/.test(n),u=jt[e?"take"+("last"==n?"Right":""):n],o=e||/^find/.test(n);u&&(jt.prototype[n]=function(){
+function n(t){return t=u.apply(jt,l([t],f)),e&&h?t[0]:t}var i=this.__wrapped__,f=e?[1]:arguments,c=i instanceof Lt,a=f[0],s=c||li(i);s&&r&&typeof a=="function"&&1!=a.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,a=o&&!h,c=c&&!p;return!o&&s?(i=c?i:new Lt(this),i=t.apply(i,f),i.__actions__.push({func:ve,args:[n],thisArg:N}),new wt(i,h)):a&&c?t.apply(this,f):(i=this.thru(n),a?e?i.value()[0]:i.value():i)})}),u("pop push shift sort splice unshift".split(" "),function(t){var n=bu[t],r=/^(?:push|sort|unshift)$/.test(t)?"tap":"thru",e=/^(?:pop|shift)$/.test(t);
+jt.prototype[t]=function(){var t=arguments;if(e&&!this.__chain__){var u=this.value();return n.apply(li(u)?u:[],t)}return this[r](function(r){return n.apply(li(r)?r:[],t)})}}),sn(Lt.prototype,function(t,n){var r=jt[n];if(r){var e=r.name+"";(co[e]||(co[e]=[])).push({name:n,func:r})}}),co[jr(N,2).name]=[{name:"wrapper",func:N}],Lt.prototype.clone=function(){var t=new Lt(this.__wrapped__);return t.__actions__=cr(this.__actions__),t.__dir__=this.__dir__,t.__filtered__=this.__filtered__,t.__iteratees__=cr(this.__iteratees__),
+t.__takeCount__=this.__takeCount__,t.__views__=cr(this.__views__),t},Lt.prototype.reverse=function(){if(this.__filtered__){var t=new Lt(this);t.__dir__=-1,t.__filtered__=true}else t=this.clone(),t.__dir__*=-1;return t},Lt.prototype.value=function(){var t,n=this.__wrapped__.value(),r=this.__dir__,e=li(n),u=0>r,o=e?n.length:0;t=o;for(var i=this.__views__,f=0,c=-1,a=i.length;++c<a;){var l=i[c],s=l.size;switch(l.type){case"drop":f+=s;break;case"dropRight":t-=s;break;case"take":t=Gu(t,f+s);break;case"takeRight":
+f=Ku(f,t-s)}}if(t={start:f,end:t},i=t.start,f=t.end,t=f-i,u=u?f:i-1,i=this.__iteratees__,f=i.length,c=0,a=Gu(t,this.__takeCount__),!e||200>o||o==t&&a==t)return Hn(n,this.__actions__);e=[];t:for(;t--&&a>c;){for(u+=r,o=-1,l=n[u];++o<f;){var h=i[o],s=h.type,h=(0,h.iteratee)(l);if(2==s)l=h;else if(!h){if(1==s)continue t;break t}}e[c++]=l}return e},jt.prototype.at=Vo,jt.prototype.chain=function(){return _e(this)},jt.prototype.commit=function(){return new wt(this.value(),this.__chain__)},jt.prototype.next=function(){
+this.__values__===N&&(this.__values__=Ve(this.value()));var t=this.__index__>=this.__values__.length,n=t?N:this.__values__[this.__index__++];return{done:t,value:n}},jt.prototype.plant=function(t){for(var n,r=this;r instanceof mt;){var e=oe(r);e.__index__=0,e.__values__=N,n?u.__wrapped__=e:n=e;var u=e,r=r.__wrapped__}return u.__wrapped__=t,n},jt.prototype.reverse=function(){var t=this.__wrapped__;return t instanceof Lt?(this.__actions__.length&&(t=new Lt(this)),t=t.reverse(),t.__actions__.push({func:ve,
+args:[se],thisArg:N}),new wt(t,this.__chain__)):this.thru(se)},jt.prototype.toJSON=jt.prototype.valueOf=jt.prototype.value=function(){return Hn(this.__wrapped__,this.__actions__)},Uu&&(jt.prototype[Uu]=ge),jt}var N,P=1/0,Z=NaN,T=/\b__p\+='';/g,q=/\b(__p\+=)''\+/g,V=/(__e\(.*?\)|\b__t\))\+'';/g,K=/&(?:amp|lt|gt|quot|#39|#96);/g,G=/[&<>"'`]/g,J=RegExp(K.source),Y=RegExp(G.source),H=/<%-([\s\S]+?)%>/g,Q=/<%([\s\S]+?)%>/g,X=/<%=([\s\S]+?)%>/g,tt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nt=/^\w*$/,rt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,et=/[\\^$.*+?()[\]{}|]/g,ut=RegExp(et.source),ot=/^\s+|\s+$/g,it=/^\s+/,ft=/\s+$/,ct=/[a-zA-Z0-9]+/g,at=/\\(\\)?/g,lt=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,st=/\w*$/,ht=/^0x/i,pt=/^[-+]0x[0-9a-f]+$/i,_t=/^0b[01]+$/i,vt=/^\[object .+?Constructor\]$/,gt=/^0o[0-7]+$/i,dt=/^(?:0|[1-9]\d*)$/,yt=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,bt=/($^)/,xt=/['\n\r\u2028\u2029\\]/g,jt="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",mt="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+jt,wt="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",At=RegExp("['\u2019]","g"),Ot=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]","g"),kt=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+wt+jt,"g"),Et=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\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]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\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\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\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]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\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\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\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\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d+",mt].join("|"),"g"),It=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),St=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Rt="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Wt={};
+Wt["[object Float32Array]"]=Wt["[object Float64Array]"]=Wt["[object Int8Array]"]=Wt["[object Int16Array]"]=Wt["[object Int32Array]"]=Wt["[object Uint8Array]"]=Wt["[object Uint8ClampedArray]"]=Wt["[object Uint16Array]"]=Wt["[object Uint32Array]"]=true,Wt["[object Arguments]"]=Wt["[object Array]"]=Wt["[object ArrayBuffer]"]=Wt["[object Boolean]"]=Wt["[object DataView]"]=Wt["[object Date]"]=Wt["[object Error]"]=Wt["[object Function]"]=Wt["[object Map]"]=Wt["[object Number]"]=Wt["[object Object]"]=Wt["[object RegExp]"]=Wt["[object Set]"]=Wt["[object String]"]=Wt["[object WeakMap]"]=false;
+var Bt={};Bt["[object Arguments]"]=Bt["[object Array]"]=Bt["[object ArrayBuffer]"]=Bt["[object DataView]"]=Bt["[object Boolean]"]=Bt["[object Date]"]=Bt["[object Float32Array]"]=Bt["[object Float64Array]"]=Bt["[object Int8Array]"]=Bt["[object Int16Array]"]=Bt["[object Int32Array]"]=Bt["[object Map]"]=Bt["[object Number]"]=Bt["[object Object]"]=Bt["[object RegExp]"]=Bt["[object Set]"]=Bt["[object String]"]=Bt["[object Symbol]"]=Bt["[object Uint8Array]"]=Bt["[object Uint8ClampedArray]"]=Bt["[object Uint16Array]"]=Bt["[object Uint32Array]"]=true,
+Bt["[object Error]"]=Bt["[object Function]"]=Bt["[object WeakMap]"]=false;var Lt={"\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"},Ct={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","`":"&#96;"},Mt={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'","&#96;":"`"},Ut={"function":true,object:true},zt={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"
+},Dt=parseFloat,$t=parseInt,Ft=Ut[typeof exports]&&exports&&!exports.nodeType?exports:N,Nt=Ut[typeof module]&&module&&!module.nodeType?module:N,Pt=Nt&&Nt.exports===Ft?Ft:N,Zt=I(Ut[typeof self]&&self),Tt=I(Ut[typeof window]&&window),qt=I(Ut[typeof this]&&this),Vt=I(Ft&&Nt&&typeof global=="object"&&global)||Tt!==(qt&&qt.window)&&Tt||Zt||qt||Function("return this")(),Kt=F();(Tt||Zt||{})._=Kt,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){return Kt}):Ft&&Nt?(Pt&&((Nt.exports=Kt)._=Kt),
+Ft._=Kt):Vt._=Kt}).call(this);
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/mapping.fp.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/mapping.fp.js
new file mode 100644
index 0000000..8adef99
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/dist/mapping.fp.js
@@ -0,0 +1,352 @@
+(function webpackUniversalModuleDefinition(root, factory) {
+	if(typeof exports === 'object' && typeof module === 'object')
+		module.exports = factory();
+	else if(typeof define === 'function' && define.amd)
+		define([], factory);
+	else if(typeof exports === 'object')
+		exports["mapping"] = factory();
+	else
+		root["mapping"] = 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) {
+
+	/** Used to map aliases to their real names. */
+	exports.aliasToReal = {
+
+	  // Lodash aliases.
+	  'each': 'forEach',
+	  'eachRight': 'forEachRight',
+	  'entries': 'toPairs',
+	  'entriesIn': 'toPairsIn',
+	  'extend': 'assignIn',
+	  'extendWith': 'assignInWith',
+	  'first': 'head',
+
+	  // Ramda aliases.
+	  '__': 'placeholder',
+	  'all': 'every',
+	  'allPass': 'overEvery',
+	  'always': 'constant',
+	  'any': 'some',
+	  'anyPass': 'overSome',
+	  'apply': 'spread',
+	  'assoc': 'set',
+	  'assocPath': 'set',
+	  'complement': 'negate',
+	  'compose': 'flowRight',
+	  'contains': 'includes',
+	  'dissoc': 'unset',
+	  'dissocPath': 'unset',
+	  'equals': 'isEqual',
+	  'identical': 'eq',
+	  'init': 'initial',
+	  'invertObj': 'invert',
+	  'juxt': 'over',
+	  'omitAll': 'omit',
+	  'nAry': 'ary',
+	  'path': 'get',
+	  'pathEq': 'matchesProperty',
+	  'pathOr': 'getOr',
+	  'paths': 'at',
+	  'pickAll': 'pick',
+	  'pipe': 'flow',
+	  'pluck': 'map',
+	  'prop': 'get',
+	  'propEq': 'matchesProperty',
+	  'propOr': 'getOr',
+	  'props': 'at',
+	  'unapply': 'rest',
+	  'unnest': 'flatten',
+	  'useWith': 'overArgs',
+	  'whereEq': 'filter',
+	  'zipObj': 'zipObject'
+	};
+
+	/** Used to map ary to method names. */
+	exports.aryMethod = {
+	  '1': [
+	    'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor',
+	    'flow', 'flowRight', 'fromPairs', 'invert', 'iteratee', 'memoize', 'method',
+	    'methodOf', 'mixin', 'over', 'overEvery', 'overSome', 'rest', 'reverse',
+	    'round', 'runInContext', 'spread', 'template', 'trim', 'trimEnd', 'trimStart',
+	    'uniqueId', 'words'
+	  ],
+	  '2': [
+	    'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindAll',
+	    'bindKey', 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
+	    'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
+	    'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith',
+	    'eq', 'every', 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast',
+	    'findLastIndex', 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth',
+	    'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight',
+	    'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf',
+	    'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch',
+	    'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues',
+	    'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'nth',
+	    'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
+	    'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
+	    'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
+	    'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
+	    'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
+	    'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight',
+	    'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars',
+	    'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith',
+	    'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject',
+	    'zipObjectDeep'
+	  ],
+	  '3': [
+	    'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
+	    'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'invokeArgs',
+	    'invokeArgsMap', 'isEqualWith', 'isMatchWith', 'flatMapDepth', 'mergeWith',
+	    'orderBy', 'padChars', 'padCharsEnd', 'padCharsStart', 'pullAllBy',
+	    'pullAllWith', 'reduce', 'reduceRight', 'replace', 'set', 'slice',
+	    'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', 'unionWith',
+	    'update', 'xorBy', 'xorWith', 'zipWith'
+	  ],
+	  '4': [
+	    'fill', 'setWith', 'updateWith'
+	  ]
+	};
+
+	/** Used to map ary to rearg configs. */
+	exports.aryRearg = {
+	  '2': [1, 0],
+	  '3': [2, 0, 1],
+	  '4': [3, 2, 0, 1]
+	};
+
+	/** Used to map method names to their iteratee ary. */
+	exports.iterateeAry = {
+	  'dropRightWhile': 1,
+	  'dropWhile': 1,
+	  'every': 1,
+	  'filter': 1,
+	  'find': 1,
+	  'findIndex': 1,
+	  'findKey': 1,
+	  'findLast': 1,
+	  'findLastIndex': 1,
+	  'findLastKey': 1,
+	  'flatMap': 1,
+	  'flatMapDeep': 1,
+	  'flatMapDepth': 1,
+	  'forEach': 1,
+	  'forEachRight': 1,
+	  'forIn': 1,
+	  'forInRight': 1,
+	  'forOwn': 1,
+	  'forOwnRight': 1,
+	  'map': 1,
+	  'mapKeys': 1,
+	  'mapValues': 1,
+	  'partition': 1,
+	  'reduce': 2,
+	  'reduceRight': 2,
+	  'reject': 1,
+	  'remove': 1,
+	  'some': 1,
+	  'takeRightWhile': 1,
+	  'takeWhile': 1,
+	  'times': 1,
+	  'transform': 2
+	};
+
+	/** Used to map method names to iteratee rearg configs. */
+	exports.iterateeRearg = {
+	  'mapKeys': [1]
+	};
+
+	/** Used to map method names to rearg configs. */
+	exports.methodRearg = {
+	  'assignInWith': [1, 2, 0],
+	  'assignWith': [1, 2, 0],
+	  'getOr': [2, 1, 0],
+	  'isEqualWith': [1, 2, 0],
+	  'isMatchWith': [2, 1, 0],
+	  'mergeWith': [1, 2, 0],
+	  'padChars': [2, 1, 0],
+	  'padCharsEnd': [2, 1, 0],
+	  'padCharsStart': [2, 1, 0],
+	  'pullAllBy': [2, 1, 0],
+	  'pullAllWith': [2, 1, 0],
+	  'setWith': [3, 1, 2, 0],
+	  'sortedIndexBy': [2, 1, 0],
+	  'sortedLastIndexBy': [2, 1, 0],
+	  'updateWith': [3, 1, 2, 0],
+	  'zipWith': [1, 2, 0]
+	};
+
+	/** Used to map method names to spread configs. */
+	exports.methodSpread = {
+	  'invokeArgs': 2,
+	  'invokeArgsMap': 2,
+	  'partial': 1,
+	  'partialRight': 1,
+	  'without': 1
+	};
+
+	/** Used to identify methods which mutate arrays or objects. */
+	exports.mutate = {
+	  'array': {
+	    'fill': true,
+	    'pull': true,
+	    'pullAll': true,
+	    'pullAllBy': true,
+	    'pullAllWith': true,
+	    'pullAt': true,
+	    'remove': true,
+	    'reverse': true
+	  },
+	  'object': {
+	    'assign': true,
+	    'assignIn': true,
+	    'assignInWith': true,
+	    'assignWith': true,
+	    'defaults': true,
+	    'defaultsDeep': true,
+	    'merge': true,
+	    'mergeWith': true
+	  },
+	  'set': {
+	    'set': true,
+	    'setWith': true,
+	    'unset': true,
+	    'update': true,
+	    'updateWith': true
+	  }
+	};
+
+	/** Used to track methods with placeholder support */
+	exports.placeholder = {
+	  'bind': true,
+	  'bindKey': true,
+	  'curry': true,
+	  'curryRight': true,
+	  'partial': true,
+	  'partialRight': true
+	};
+
+	/** Used to map real names to their aliases. */
+	exports.realToAlias = (function() {
+	  var hasOwnProperty = Object.prototype.hasOwnProperty,
+	      object = exports.aliasToReal,
+	      result = {};
+
+	  for (var key in object) {
+	    var value = object[key];
+	    if (hasOwnProperty.call(result, value)) {
+	      result[value].push(key);
+	    } else {
+	      result[value] = [key];
+	    }
+	  }
+	  return result;
+	}());
+
+	/** Used to map method names to other names. */
+	exports.remap = {
+	  'curryN': 'curry',
+	  'curryRightN': 'curryRight',
+	  'getOr': 'get',
+	  'invokeArgs': 'invoke',
+	  'invokeArgsMap': 'invokeMap',
+	  'padChars': 'pad',
+	  'padCharsEnd': 'padEnd',
+	  'padCharsStart': 'padStart',
+	  'restFrom': 'rest',
+	  'spreadFrom': 'spread',
+	  'trimChars': 'trim',
+	  'trimCharsEnd': 'trimEnd',
+	  'trimCharsStart': 'trimStart'
+	};
+
+	/** Used to track methods that skip fixing their arity. */
+	exports.skipFixed = {
+	  'castArray': true,
+	  'flow': true,
+	  'flowRight': true,
+	  'iteratee': true,
+	  'mixin': true,
+	  'runInContext': true
+	};
+
+	/** Used to track methods that skip rearranging arguments. */
+	exports.skipRearg = {
+	  'add': true,
+	  'assign': true,
+	  'assignIn': true,
+	  'bind': true,
+	  'bindKey': true,
+	  'concat': true,
+	  'difference': true,
+	  'divide': true,
+	  'eq': true,
+	  'gt': true,
+	  'gte': true,
+	  'isEqual': true,
+	  'lt': true,
+	  'lte': true,
+	  'matchesProperty': true,
+	  'merge': true,
+	  'multiply': true,
+	  'overArgs': true,
+	  'partial': true,
+	  'partialRight': true,
+	  'random': true,
+	  'range': true,
+	  'rangeRight': true,
+	  'subtract': true,
+	  'without': true,
+	  'zip': true,
+	  'zipObject': true
+	};
+
+
+/***/ }
+/******/ ])
+});
+;
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/doc/README.md b/views/ngXosViews/serviceGrid/src/vendor/lodash/doc/README.md
new file mode 100644
index 0000000..f9da2b3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/doc/README.md
@@ -0,0 +1,10738 @@
+# <a href="https://lodash.com/">lodash</a> <span>v4.11.2</span>
+
+<!-- div class="toc-container" -->
+
+<!-- div -->
+
+## `Array`
+* <a href="#_chunkarray-size1">`_.chunk`</a>
+* <a href="#_compactarray">`_.compact`</a>
+* <a href="#_concatarray-values">`_.concat`</a>
+* <a href="#_differencearray-values">`_.difference`</a>
+* <a href="#_differencebyarray-values-iteratee_identity">`_.differenceBy`</a>
+* <a href="#_differencewitharray-values-comparator">`_.differenceWith`</a>
+* <a href="#_droparray-n1">`_.drop`</a>
+* <a href="#_droprightarray-n1">`_.dropRight`</a>
+* <a href="#_droprightwhilearray-predicate_identity">`_.dropRightWhile`</a>
+* <a href="#_dropwhilearray-predicate_identity">`_.dropWhile`</a>
+* <a href="#_fillarray-value-start0-endarraylength">`_.fill`</a>
+* <a href="#_findindexarray-predicate_identity">`_.findIndex`</a>
+* <a href="#_findlastindexarray-predicate_identity">`_.findLastIndex`</a>
+* <a href="#_headarray" class="alias">`_.first` -> `head`</a>
+* <a href="#_flattenarray">`_.flatten`</a>
+* <a href="#_flattendeeparray">`_.flattenDeep`</a>
+* <a href="#_flattendeptharray-depth1">`_.flattenDepth`</a>
+* <a href="#_frompairspairs">`_.fromPairs`</a>
+* <a href="#_headarray">`_.head`</a>
+* <a href="#_indexofarray-value-fromindex0">`_.indexOf`</a>
+* <a href="#_initialarray">`_.initial`</a>
+* <a href="#_intersectionarrays">`_.intersection`</a>
+* <a href="#_intersectionbyarrays-iteratee_identity">`_.intersectionBy`</a>
+* <a href="#_intersectionwitharrays-comparator">`_.intersectionWith`</a>
+* <a href="#_joinarray-separator-">`_.join`</a>
+* <a href="#_lastarray">`_.last`</a>
+* <a href="#_lastindexofarray-value-fromindexarraylength-1">`_.lastIndexOf`</a>
+* <a href="#_ntharray-n0">`_.nth`</a>
+* <a href="#_pullarray-values">`_.pull`</a>
+* <a href="#_pullallarray-values">`_.pullAll`</a>
+* <a href="#_pullallbyarray-values-iteratee_identity">`_.pullAllBy`</a>
+* <a href="#_pullallwitharray-values-comparator">`_.pullAllWith`</a>
+* <a href="#_pullatarray-indexes">`_.pullAt`</a>
+* <a href="#_removearray-predicate_identity">`_.remove`</a>
+* <a href="#_reversearray">`_.reverse`</a>
+* <a href="#_slicearray-start0-endarraylength">`_.slice`</a>
+* <a href="#_sortedindexarray-value">`_.sortedIndex`</a>
+* <a href="#_sortedindexbyarray-value-iteratee_identity">`_.sortedIndexBy`</a>
+* <a href="#_sortedindexofarray-value">`_.sortedIndexOf`</a>
+* <a href="#_sortedlastindexarray-value">`_.sortedLastIndex`</a>
+* <a href="#_sortedlastindexbyarray-value-iteratee_identity">`_.sortedLastIndexBy`</a>
+* <a href="#_sortedlastindexofarray-value">`_.sortedLastIndexOf`</a>
+* <a href="#_sorteduniqarray">`_.sortedUniq`</a>
+* <a href="#_sorteduniqbyarray-iteratee">`_.sortedUniqBy`</a>
+* <a href="#_tailarray">`_.tail`</a>
+* <a href="#_takearray-n1">`_.take`</a>
+* <a href="#_takerightarray-n1">`_.takeRight`</a>
+* <a href="#_takerightwhilearray-predicate_identity">`_.takeRightWhile`</a>
+* <a href="#_takewhilearray-predicate_identity">`_.takeWhile`</a>
+* <a href="#_unionarrays">`_.union`</a>
+* <a href="#_unionbyarrays-iteratee_identity">`_.unionBy`</a>
+* <a href="#_unionwitharrays-comparator">`_.unionWith`</a>
+* <a href="#_uniqarray">`_.uniq`</a>
+* <a href="#_uniqbyarray-iteratee_identity">`_.uniqBy`</a>
+* <a href="#_uniqwitharray-comparator">`_.uniqWith`</a>
+* <a href="#_unziparray">`_.unzip`</a>
+* <a href="#_unzipwitharray-iteratee_identity">`_.unzipWith`</a>
+* <a href="#_withoutarray-values">`_.without`</a>
+* <a href="#_xorarrays">`_.xor`</a>
+* <a href="#_xorbyarrays-iteratee_identity">`_.xorBy`</a>
+* <a href="#_xorwitharrays-comparator">`_.xorWith`</a>
+* <a href="#_ziparrays">`_.zip`</a>
+* <a href="#_zipobjectprops-values">`_.zipObject`</a>
+* <a href="#_zipobjectdeepprops-values">`_.zipObjectDeep`</a>
+* <a href="#_zipwitharrays-iteratee_identity">`_.zipWith`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Collection`
+* <a href="#_countbycollection-iteratee_identity">`_.countBy`</a>
+* <a href="#_foreachcollection-iteratee_identity" class="alias">`_.each` -> `forEach`</a>
+* <a href="#_foreachrightcollection-iteratee_identity" class="alias">`_.eachRight` -> `forEachRight`</a>
+* <a href="#_everycollection-predicate_identity">`_.every`</a>
+* <a href="#_filtercollection-predicate_identity">`_.filter`</a>
+* <a href="#_findcollection-predicate_identity">`_.find`</a>
+* <a href="#_findlastcollection-predicate_identity">`_.findLast`</a>
+* <a href="#_flatmapcollection-iteratee_identity">`_.flatMap`</a>
+* <a href="#_flatmapdeepcollection-iteratee_identity">`_.flatMapDeep`</a>
+* <a href="#_flatmapdepthcollection-iteratee_identity-depth1">`_.flatMapDepth`</a>
+* <a href="#_foreachcollection-iteratee_identity">`_.forEach`</a>
+* <a href="#_foreachrightcollection-iteratee_identity">`_.forEachRight`</a>
+* <a href="#_groupbycollection-iteratee_identity">`_.groupBy`</a>
+* <a href="#_includescollection-value-fromindex0">`_.includes`</a>
+* <a href="#_invokemapcollection-path-args">`_.invokeMap`</a>
+* <a href="#_keybycollection-iteratee_identity">`_.keyBy`</a>
+* <a href="#_mapcollection-iteratee_identity">`_.map`</a>
+* <a href="#_orderbycollection-iteratees_identity-orders">`_.orderBy`</a>
+* <a href="#_partitioncollection-predicate_identity">`_.partition`</a>
+* <a href="#_reducecollection-iteratee_identity-accumulator">`_.reduce`</a>
+* <a href="#_reducerightcollection-iteratee_identity-accumulator">`_.reduceRight`</a>
+* <a href="#_rejectcollection-predicate_identity">`_.reject`</a>
+* <a href="#_samplecollection">`_.sample`</a>
+* <a href="#_samplesizecollection-n1">`_.sampleSize`</a>
+* <a href="#_shufflecollection">`_.shuffle`</a>
+* <a href="#_sizecollection">`_.size`</a>
+* <a href="#_somecollection-predicate_identity">`_.some`</a>
+* <a href="#_sortbycollection-iteratees_identity">`_.sortBy`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Date`
+* <a href="#_now">`_.now`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Function`
+* <a href="#_aftern-func">`_.after`</a>
+* <a href="#_aryfunc-nfunclength">`_.ary`</a>
+* <a href="#_beforen-func">`_.before`</a>
+* <a href="#_bindfunc-thisarg-partials">`_.bind`</a>
+* <a href="#_bindkeyobject-key-partials">`_.bindKey`</a>
+* <a href="#_curryfunc-arityfunclength">`_.curry`</a>
+* <a href="#_curryrightfunc-arityfunclength">`_.curryRight`</a>
+* <a href="#_debouncefunc-wait0-options-optionsleadingfalse-optionsmaxwait-optionstrailingtrue">`_.debounce`</a>
+* <a href="#_deferfunc-args">`_.defer`</a>
+* <a href="#_delayfunc-wait-args">`_.delay`</a>
+* <a href="#_flipfunc">`_.flip`</a>
+* <a href="#_memoizefunc-resolver">`_.memoize`</a>
+* <a href="#_negatepredicate">`_.negate`</a>
+* <a href="#_oncefunc">`_.once`</a>
+* <a href="#_overargsfunc">`_.overArgs`</a>
+* <a href="#_partialfunc-partials">`_.partial`</a>
+* <a href="#_partialrightfunc-partials">`_.partialRight`</a>
+* <a href="#_reargfunc-indexes">`_.rearg`</a>
+* <a href="#_restfunc-startfunclength-1">`_.rest`</a>
+* <a href="#_spreadfunc-start0">`_.spread`</a>
+* <a href="#_throttlefunc-wait0-options-optionsleadingtrue-optionstrailingtrue">`_.throttle`</a>
+* <a href="#_unaryfunc">`_.unary`</a>
+* <a href="#_wrapvalue-wrapperidentity">`_.wrap`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Lang`
+* <a href="#_castarrayvalue">`_.castArray`</a>
+* <a href="#_clonevalue">`_.clone`</a>
+* <a href="#_clonedeepvalue">`_.cloneDeep`</a>
+* <a href="#_clonedeepwithvalue-customizer">`_.cloneDeepWith`</a>
+* <a href="#_clonewithvalue-customizer">`_.cloneWith`</a>
+* <a href="#_eqvalue-other">`_.eq`</a>
+* <a href="#_gtvalue-other">`_.gt`</a>
+* <a href="#_gtevalue-other">`_.gte`</a>
+* <a href="#_isargumentsvalue">`_.isArguments`</a>
+* <a href="#_isarrayvalue">`_.isArray`</a>
+* <a href="#_isarraybuffervalue">`_.isArrayBuffer`</a>
+* <a href="#_isarraylikevalue">`_.isArrayLike`</a>
+* <a href="#_isarraylikeobjectvalue">`_.isArrayLikeObject`</a>
+* <a href="#_isbooleanvalue">`_.isBoolean`</a>
+* <a href="#_isbuffervalue">`_.isBuffer`</a>
+* <a href="#_isdatevalue">`_.isDate`</a>
+* <a href="#_iselementvalue">`_.isElement`</a>
+* <a href="#_isemptyvalue">`_.isEmpty`</a>
+* <a href="#_isequalvalue-other">`_.isEqual`</a>
+* <a href="#_isequalwithvalue-other-customizer">`_.isEqualWith`</a>
+* <a href="#_iserrorvalue">`_.isError`</a>
+* <a href="#_isfinitevalue">`_.isFinite`</a>
+* <a href="#_isfunctionvalue">`_.isFunction`</a>
+* <a href="#_isintegervalue">`_.isInteger`</a>
+* <a href="#_islengthvalue">`_.isLength`</a>
+* <a href="#_ismapvalue">`_.isMap`</a>
+* <a href="#_ismatchobject-source">`_.isMatch`</a>
+* <a href="#_ismatchwithobject-source-customizer">`_.isMatchWith`</a>
+* <a href="#_isnanvalue">`_.isNaN`</a>
+* <a href="#_isnativevalue">`_.isNative`</a>
+* <a href="#_isnilvalue">`_.isNil`</a>
+* <a href="#_isnullvalue">`_.isNull`</a>
+* <a href="#_isnumbervalue">`_.isNumber`</a>
+* <a href="#_isobjectvalue">`_.isObject`</a>
+* <a href="#_isobjectlikevalue">`_.isObjectLike`</a>
+* <a href="#_isplainobjectvalue">`_.isPlainObject`</a>
+* <a href="#_isregexpvalue">`_.isRegExp`</a>
+* <a href="#_issafeintegervalue">`_.isSafeInteger`</a>
+* <a href="#_issetvalue">`_.isSet`</a>
+* <a href="#_isstringvalue">`_.isString`</a>
+* <a href="#_issymbolvalue">`_.isSymbol`</a>
+* <a href="#_istypedarrayvalue">`_.isTypedArray`</a>
+* <a href="#_isundefinedvalue">`_.isUndefined`</a>
+* <a href="#_isweakmapvalue">`_.isWeakMap`</a>
+* <a href="#_isweaksetvalue">`_.isWeakSet`</a>
+* <a href="#_ltvalue-other">`_.lt`</a>
+* <a href="#_ltevalue-other">`_.lte`</a>
+* <a href="#_toarrayvalue">`_.toArray`</a>
+* <a href="#_tointegervalue">`_.toInteger`</a>
+* <a href="#_tolengthvalue">`_.toLength`</a>
+* <a href="#_tonumbervalue">`_.toNumber`</a>
+* <a href="#_toplainobjectvalue">`_.toPlainObject`</a>
+* <a href="#_tosafeintegervalue">`_.toSafeInteger`</a>
+* <a href="#_tostringvalue">`_.toString`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Math`
+* <a href="#_addaugend-addend">`_.add`</a>
+* <a href="#_ceilnumber-precision0">`_.ceil`</a>
+* <a href="#_dividedividend-divisor">`_.divide`</a>
+* <a href="#_floornumber-precision0">`_.floor`</a>
+* <a href="#_maxarray">`_.max`</a>
+* <a href="#_maxbyarray-iteratee_identity">`_.maxBy`</a>
+* <a href="#_meanarray">`_.mean`</a>
+* <a href="#_meanbyarray-iteratee_identity">`_.meanBy`</a>
+* <a href="#_minarray">`_.min`</a>
+* <a href="#_minbyarray-iteratee_identity">`_.minBy`</a>
+* <a href="#_multiplymultiplier-multiplicand">`_.multiply`</a>
+* <a href="#_roundnumber-precision0">`_.round`</a>
+* <a href="#_subtractminuend-subtrahend">`_.subtract`</a>
+* <a href="#_sumarray">`_.sum`</a>
+* <a href="#_sumbyarray-iteratee_identity">`_.sumBy`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Number`
+* <a href="#_clampnumber-lower-upper">`_.clamp`</a>
+* <a href="#_inrangenumber-start0-end">`_.inRange`</a>
+* <a href="#_randomlower0-upper1-floating">`_.random`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Object`
+* <a href="#_assignobject-sources">`_.assign`</a>
+* <a href="#_assigninobject-sources">`_.assignIn`</a>
+* <a href="#_assigninwithobject-sources-customizer">`_.assignInWith`</a>
+* <a href="#_assignwithobject-sources-customizer">`_.assignWith`</a>
+* <a href="#_atobject-paths">`_.at`</a>
+* <a href="#_createprototype-properties">`_.create`</a>
+* <a href="#_defaultsobject-sources">`_.defaults`</a>
+* <a href="#_defaultsdeepobject-sources">`_.defaultsDeep`</a>
+* <a href="#_topairsobject" class="alias">`_.entries` -> `toPairs`</a>
+* <a href="#_topairsinobject" class="alias">`_.entriesIn` -> `toPairsIn`</a>
+* <a href="#_assigninobject-sources" class="alias">`_.extend` -> `assignIn`</a>
+* <a href="#_assigninwithobject-sources-customizer" class="alias">`_.extendWith` -> `assignInWith`</a>
+* <a href="#_findkeyobject-predicate_identity">`_.findKey`</a>
+* <a href="#_findlastkeyobject-predicate_identity">`_.findLastKey`</a>
+* <a href="#_forinobject-iteratee_identity">`_.forIn`</a>
+* <a href="#_forinrightobject-iteratee_identity">`_.forInRight`</a>
+* <a href="#_forownobject-iteratee_identity">`_.forOwn`</a>
+* <a href="#_forownrightobject-iteratee_identity">`_.forOwnRight`</a>
+* <a href="#_functionsobject">`_.functions`</a>
+* <a href="#_functionsinobject">`_.functionsIn`</a>
+* <a href="#_getobject-path-defaultvalue">`_.get`</a>
+* <a href="#_hasobject-path">`_.has`</a>
+* <a href="#_hasinobject-path">`_.hasIn`</a>
+* <a href="#_invertobject">`_.invert`</a>
+* <a href="#_invertbyobject-iteratee_identity">`_.invertBy`</a>
+* <a href="#_invokeobject-path-args">`_.invoke`</a>
+* <a href="#_keysobject">`_.keys`</a>
+* <a href="#_keysinobject">`_.keysIn`</a>
+* <a href="#_mapkeysobject-iteratee_identity">`_.mapKeys`</a>
+* <a href="#_mapvaluesobject-iteratee_identity">`_.mapValues`</a>
+* <a href="#_mergeobject-sources">`_.merge`</a>
+* <a href="#_mergewithobject-sources-customizer">`_.mergeWith`</a>
+* <a href="#_omitobject-props">`_.omit`</a>
+* <a href="#_omitbyobject-predicate_identity">`_.omitBy`</a>
+* <a href="#_pickobject-props">`_.pick`</a>
+* <a href="#_pickbyobject-predicate_identity">`_.pickBy`</a>
+* <a href="#_resultobject-path-defaultvalue">`_.result`</a>
+* <a href="#_setobject-path-value">`_.set`</a>
+* <a href="#_setwithobject-path-value-customizer">`_.setWith`</a>
+* <a href="#_topairsobject">`_.toPairs`</a>
+* <a href="#_topairsinobject">`_.toPairsIn`</a>
+* <a href="#_transformobject-iteratee_identity-accumulator">`_.transform`</a>
+* <a href="#_unsetobject-path">`_.unset`</a>
+* <a href="#_updateobject-path-updater">`_.update`</a>
+* <a href="#_updatewithobject-path-updater-customizer">`_.updateWith`</a>
+* <a href="#_valuesobject">`_.values`</a>
+* <a href="#_valuesinobject">`_.valuesIn`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Seq`
+* <a href="#_value">`_`</a>
+* <a href="#_chainvalue">`_.chain`</a>
+* <a href="#_tapvalue-interceptor">`_.tap`</a>
+* <a href="#_thruvalue-interceptor">`_.thru`</a>
+* <a href="#_prototypesymboliterator">`_.prototype[Symbol.iterator]`</a>
+* <a href="#_prototypeatpaths">`_.prototype.at`</a>
+* <a href="#_prototypechain">`_.prototype.chain`</a>
+* <a href="#_prototypecommit">`_.prototype.commit`</a>
+* <a href="#_prototypenext">`_.prototype.next`</a>
+* <a href="#_prototypeplantvalue">`_.prototype.plant`</a>
+* <a href="#_prototypereverse">`_.prototype.reverse`</a>
+* <a href="#_prototypevalue" class="alias">`_.prototype.toJSON` -> `value`</a>
+* <a href="#_prototypevalue">`_.prototype.value`</a>
+* <a href="#_prototypevalue" class="alias">`_.prototype.valueOf` -> `value`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `String`
+* <a href="#_camelcasestring">`_.camelCase`</a>
+* <a href="#_capitalizestring">`_.capitalize`</a>
+* <a href="#_deburrstring">`_.deburr`</a>
+* <a href="#_endswithstring-target-positionstringlength">`_.endsWith`</a>
+* <a href="#_escapestring">`_.escape`</a>
+* <a href="#_escaperegexpstring">`_.escapeRegExp`</a>
+* <a href="#_kebabcasestring">`_.kebabCase`</a>
+* <a href="#_lowercasestring">`_.lowerCase`</a>
+* <a href="#_lowerfirststring">`_.lowerFirst`</a>
+* <a href="#_padstring-length0-chars">`_.pad`</a>
+* <a href="#_padendstring-length0-chars">`_.padEnd`</a>
+* <a href="#_padstartstring-length0-chars">`_.padStart`</a>
+* <a href="#_parseintstring-radix10">`_.parseInt`</a>
+* <a href="#_repeatstring-n1">`_.repeat`</a>
+* <a href="#_replacestring-pattern-replacement">`_.replace`</a>
+* <a href="#_snakecasestring">`_.snakeCase`</a>
+* <a href="#_splitstring-separator-limit">`_.split`</a>
+* <a href="#_startcasestring">`_.startCase`</a>
+* <a href="#_startswithstring-target-position0">`_.startsWith`</a>
+* <a href="#_templatestring-options-optionsescape_templatesettingsescape-optionsevaluate_templatesettingsevaluate-optionsimports_templatesettingsimports-optionsinterpolate_templatesettingsinterpolate-optionssourceurllodashtemplatesourcesn-optionsvariableobj">`_.template`</a>
+* <a href="#_tolowerstring">`_.toLower`</a>
+* <a href="#_toupperstring">`_.toUpper`</a>
+* <a href="#_trimstring-charswhitespace">`_.trim`</a>
+* <a href="#_trimendstring-charswhitespace">`_.trimEnd`</a>
+* <a href="#_trimstartstring-charswhitespace">`_.trimStart`</a>
+* <a href="#_truncatestring-options-optionslength30-optionsomission-optionsseparator">`_.truncate`</a>
+* <a href="#_unescapestring">`_.unescape`</a>
+* <a href="#_uppercasestring">`_.upperCase`</a>
+* <a href="#_upperfirststring">`_.upperFirst`</a>
+* <a href="#_wordsstring-pattern">`_.words`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Util`
+* <a href="#_attemptfunc-args">`_.attempt`</a>
+* <a href="#_bindallobject-methodnames">`_.bindAll`</a>
+* <a href="#_condpairs">`_.cond`</a>
+* <a href="#_conformssource">`_.conforms`</a>
+* <a href="#_constantvalue">`_.constant`</a>
+* <a href="#_flowfuncs">`_.flow`</a>
+* <a href="#_flowrightfuncs">`_.flowRight`</a>
+* <a href="#_identityvalue">`_.identity`</a>
+* <a href="#_iterateefunc_identity">`_.iteratee`</a>
+* <a href="#_matchessource">`_.matches`</a>
+* <a href="#_matchespropertypath-srcvalue">`_.matchesProperty`</a>
+* <a href="#_methodpath-args">`_.method`</a>
+* <a href="#_methodofobject-args">`_.methodOf`</a>
+* <a href="#_mixinobjectlodash-source-options-optionschaintrue">`_.mixin`</a>
+* <a href="#_noconflict">`_.noConflict`</a>
+* <a href="#_noop">`_.noop`</a>
+* <a href="#_nthargn0">`_.nthArg`</a>
+* <a href="#_overiteratees_identity">`_.over`</a>
+* <a href="#_overeverypredicates_identity">`_.overEvery`</a>
+* <a href="#_oversomepredicates_identity">`_.overSome`</a>
+* <a href="#_propertypath">`_.property`</a>
+* <a href="#_propertyofobject">`_.propertyOf`</a>
+* <a href="#_rangestart0-end-step1">`_.range`</a>
+* <a href="#_rangerightstart0-end-step1">`_.rangeRight`</a>
+* <a href="#_runincontextcontextroot">`_.runInContext`</a>
+* <a href="#_timesn-iteratee_identity">`_.times`</a>
+* <a href="#_topathvalue">`_.toPath`</a>
+* <a href="#_uniqueidprefix">`_.uniqueId`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Properties`
+* <a href="#_version">`_.VERSION`</a>
+* <a href="#_templatesettings">`_.templateSettings`</a>
+* <a href="#_templatesettingsescape">`_.templateSettings.escape`</a>
+* <a href="#_templatesettingsevaluate">`_.templateSettings.evaluate`</a>
+* <a href="#_templatesettingsimports">`_.templateSettings.imports`</a>
+* <a href="#_templatesettingsinterpolate">`_.templateSettings.interpolate`</a>
+* <a href="#_templatesettingsvariable">`_.templateSettings.variable`</a>
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Methods`
+* <a href="#_templatesettingsimports_">`_.templateSettings.imports._`</a>
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div class="doc-container" -->
+
+<!-- div -->
+
+## `“Array” Methods`
+
+<!-- div -->
+
+### <a id="_chunkarray-size1"></a>`_.chunk(array, [size=1])`
+<a href="#_chunkarray-size1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L5982 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.chunk "See the npm package")
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to process.
+2. `[size=1]` *(number)*: The length of each chunk
+
+#### Returns
+*(Array)*: Returns the new array containing chunks.
+
+#### Example
+```js
+_.chunk(['a', 'b', 'c', 'd'], 2);
+// => [['a', 'b'], ['c', 'd']]
+
+_.chunk(['a', 'b', 'c', 'd'], 3);
+// => [['a', 'b', 'c'], ['d']]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_compactarray"></a>`_.compact(array)`
+<a href="#_compactarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6017 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.compact "See the npm package")
+
+Creates an array with all falsey values removed. The values `false`, `null`,
+`0`, `""`, `undefined`, and `NaN` are falsey.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to compact.
+
+#### Returns
+*(Array)*: Returns the new array of filtered values.
+
+#### Example
+```js
+_.compact([0, 1, false, 2, '', 3]);
+// => [1, 2, 3]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_concatarray-values"></a>`_.concat(array, [values])`
+<a href="#_concatarray-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6054 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.concat "See the npm package")
+
+Creates a new array concatenating `array` with any additional arrays
+and/or values.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to concatenate.
+2. `[values]` *(...&#42;)*: The values to concatenate.
+
+#### Returns
+*(Array)*: Returns the new concatenated array.
+
+#### Example
+```js
+var array = [1];
+var other = _.concat(array, 2, [3], [[4]]);
+
+console.log(other);
+// => [1, 2, 3, [4]]
+
+console.log(array);
+// => [1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_differencearray-values"></a>`_.difference(array, [values])`
+<a href="#_differencearray-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6087 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.difference "See the npm package")
+
+Creates an array of unique `array` values not included in the other given
+arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons. The order of result values is determined by the
+order they occur in the first array.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+2. `[values]` *(...Array)*: The values to exclude.
+
+#### Returns
+*(Array)*: Returns the new array of filtered values.
+
+#### Example
+```js
+_.difference([3, 2, 1], [4, 2]);
+// => [3, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_differencebyarray-values-iteratee_identity"></a>`_.differenceBy(array, [values], [iteratee=_.identity])`
+<a href="#_differencebyarray-values-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6117 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.differenceby "See the npm package")
+
+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. Result values are chosen from the first array.
+The iteratee is invoked with one argument: *(value)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+2. `[values]` *(...Array)*: The values to exclude.
+3. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of filtered values.
+
+#### Example
+```js
+_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
+// => [3.1, 1.3]
+
+// The `_.property` iteratee shorthand.
+_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+// => [{ 'x': 2 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_differencewitharray-values-comparator"></a>`_.differenceWith(array, [values], [comparator])`
+<a href="#_differencewitharray-values-comparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6148 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.differencewith "See the npm package")
+
+This method is like `_.difference` except that it accepts `comparator`
+which is invoked to compare elements of `array` to `values`. Result values
+are chosen from the first array. The comparator is invoked with two arguments:<br>
+*(arrVal, othVal)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+2. `[values]` *(...Array)*: The values to exclude.
+3. `[comparator]` *(Function)*: The comparator invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of filtered values.
+
+#### Example
+```js
+var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
+
+_.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
+// => [{ 'x': 2, 'y': 1 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_droparray-n1"></a>`_.drop(array, [n=1])`
+<a href="#_droparray-n1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6183 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.drop "See the npm package")
+
+Creates a slice of `array` with `n` elements dropped from the beginning.
+
+#### Since
+0.5.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[n=1]` *(number)*: The number of elements to drop.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+_.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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_droprightarray-n1"></a>`_.dropRight(array, [n=1])`
+<a href="#_droprightarray-n1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6217 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.dropright "See the npm package")
+
+Creates a slice of `array` with `n` elements dropped from the end.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[n=1]` *(number)*: The number of elements to drop.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+_.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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_droprightwhilearray-predicate_identity"></a>`_.dropRightWhile(array, [predicate=_.identity])`
+<a href="#_droprightwhilearray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6263 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package")
+
+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)*.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_dropwhilearray-predicate_identity"></a>`_.dropWhile(array, [predicate=_.identity])`
+<a href="#_dropwhilearray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6305 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.dropwhile "See the npm package")
+
+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)*.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_fillarray-value-start0-endarraylength"></a>`_.fill(array, value, [start=0], [end=array.length])`
+<a href="#_fillarray-value-start0-endarraylength">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6340 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.fill "See the npm package")
+
+Fills elements of `array` with `value` from `start` up to, but not
+including, `end`.
+<br>
+<br>
+**Note:** This method mutates `array`.
+
+#### Since
+3.2.0
+#### Arguments
+1. `array` *(Array)*: The array to fill.
+2. `value` *(&#42;)*: The value to fill `array` with.
+3. `[start=0]` *(number)*: The start position.
+4. `[end=array.length]` *(number)*: The end position.
+
+#### Returns
+*(Array)*: Returns `array`.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_findindexarray-predicate_identity"></a>`_.findIndex(array, [predicate=_.identity])`
+<a href="#_findindexarray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6387 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.findindex "See the npm package")
+
+This method is like `_.find` except that it returns the index of the first
+element `predicate` returns truthy for instead of the element itself.
+
+#### Since
+1.1.0
+#### Arguments
+1. `array` *(Array)*: The array to search.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(number)*: Returns the index of the found element, else `-1`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_findlastindexarray-predicate_identity"></a>`_.findLastIndex(array, [predicate=_.identity])`
+<a href="#_findlastindexarray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6428 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.findlastindex "See the npm package")
+
+This method is like `_.findIndex` except that it iterates over elements
+of `collection` from right to left.
+
+#### Since
+2.0.0
+#### Arguments
+1. `array` *(Array)*: The array to search.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(number)*: Returns the index of the found element, else `-1`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flattenarray"></a>`_.flatten(array)`
+<a href="#_flattenarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6448 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flatten "See the npm package")
+
+Flattens `array` a single level deep.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to flatten.
+
+#### Returns
+*(Array)*: Returns the new flattened array.
+
+#### Example
+```js
+_.flatten([1, [2, [3, [4]], 5]]);
+// => [1, 2, [3, [4]], 5]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flattendeeparray"></a>`_.flattenDeep(array)`
+<a href="#_flattendeeparray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6467 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flattendeep "See the npm package")
+
+Recursively flattens `array`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to flatten.
+
+#### Returns
+*(Array)*: Returns the new flattened array.
+
+#### Example
+```js
+_.flattenDeep([1, [2, [3, [4]], 5]]);
+// => [1, 2, 3, 4, 5]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flattendeptharray-depth1"></a>`_.flattenDepth(array, [depth=1])`
+<a href="#_flattendeptharray-depth1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6492 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flattendepth "See the npm package")
+
+Recursively flatten `array` up to `depth` times.
+
+#### Since
+4.4.0
+#### Arguments
+1. `array` *(Array)*: The array to flatten.
+2. `[depth=1]` *(number)*: The maximum recursion depth.
+
+#### Returns
+*(Array)*: Returns the new flattened array.
+
+#### Example
+```js
+var array = [1, [2, [3, [4]], 5]];
+
+_.flattenDepth(array, 1);
+// => [1, 2, [3, [4]], 5]
+
+_.flattenDepth(array, 2);
+// => [1, 2, 3, [4], 5]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_frompairspairs"></a>`_.fromPairs(pairs)`
+<a href="#_frompairspairs">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6516 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.frompairs "See the npm package")
+
+The inverse of `_.toPairs`; this method returns an object composed
+from key-value `pairs`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `pairs` *(Array)*: The key-value pairs.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+_.fromPairs([['fred', 30], ['barney', 40]]);
+// => { 'fred': 30, 'barney': 40 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_headarray"></a>`_.head(array)`
+<a href="#_headarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6546 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.head "See the npm package")
+
+Gets the first element of `array`.
+
+#### Since
+0.1.0
+#### Aliases
+*_.first*
+
+#### Arguments
+1. `array` *(Array)*: The array to query.
+
+#### Returns
+*(&#42;)*: Returns the first element of `array`.
+
+#### Example
+```js
+_.head([1, 2, 3]);
+// => 1
+
+_.head([]);
+// => undefined
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_indexofarray-value-fromindex0"></a>`_.indexOf(array, value, [fromIndex=0])`
+<a href="#_indexofarray-value-fromindex0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6573 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.indexof "See the npm package")
+
+Gets the index at which the first occurrence of `value` is found in `array`
+using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons. If `fromIndex` is negative, it's used as the
+offset from the end of `array`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to search.
+2. `value` *(&#42;)*: The value to search for.
+3. `[fromIndex=0]` *(number)*: The index to search from.
+
+#### Returns
+*(number)*: Returns the index of the matched value, else `-1`.
+
+#### Example
+```js
+_.indexOf([1, 2, 1, 2], 2);
+// => 1
+
+// Search from the `fromIndex`.
+_.indexOf([1, 2, 1, 2], 2, 2);
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_initialarray"></a>`_.initial(array)`
+<a href="#_initialarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6599 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.initial "See the npm package")
+
+Gets all but the last element of `array`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+_.initial([1, 2, 3]);
+// => [1, 2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_intersectionarrays"></a>`_.intersection([arrays])`
+<a href="#_intersectionarrays">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6620 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.intersection "See the npm package")
+
+Creates an array of unique values that are included in all given arrays
+using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons. The order of result values is determined by the
+order they occur in the first array.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+
+#### Returns
+*(Array)*: Returns the new array of intersecting values.
+
+#### Example
+```js
+_.intersection([2, 1], [4, 2], [1, 2]);
+// => [2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_intersectionbyarrays-iteratee_identity"></a>`_.intersectionBy([arrays], [iteratee=_.identity])`
+<a href="#_intersectionbyarrays-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6650 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.intersectionby "See the npm package")
+
+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. Result values are chosen from the first array.
+The iteratee is invoked with one argument: *(value)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of intersecting values.
+
+#### Example
+```js
+_.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+// => [2.1]
+
+// The `_.property` iteratee shorthand.
+_.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+// => [{ 'x': 1 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_intersectionwitharrays-comparator"></a>`_.intersectionWith([arrays], [comparator])`
+<a href="#_intersectionwitharrays-comparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6685 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.intersectionwith "See the npm package")
+
+This method is like `_.intersection` except that it accepts `comparator`
+which is invoked to compare elements of `arrays`. Result values are chosen
+from the first array. The comparator is invoked with two arguments:<br>
+*(arrVal, othVal)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+2. `[comparator]` *(Function)*: The comparator invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of intersecting values.
+
+#### Example
+```js
+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 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_joinarray-separator-"></a>`_.join(array, [separator=','])`
+<a href="#_joinarray-separator-">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6714 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.join "See the npm package")
+
+Converts all elements in `array` into a string separated by `separator`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to convert.
+2. `[separator=',']` *(string)*: The element separator.
+
+#### Returns
+*(string)*: Returns the joined string.
+
+#### Example
+```js
+_.join(['a', 'b', 'c'], '~');
+// => 'a~b~c'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_lastarray"></a>`_.last(array)`
+<a href="#_lastarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6732 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.last "See the npm package")
+
+Gets the last element of `array`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+
+#### Returns
+*(&#42;)*: Returns the last element of `array`.
+
+#### Example
+```js
+_.last([1, 2, 3]);
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_lastindexofarray-value-fromindexarraylength-1"></a>`_.lastIndexOf(array, value, [fromIndex=array.length-1])`
+<a href="#_lastindexofarray-value-fromindexarraylength-1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6758 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.lastindexof "See the npm package")
+
+This method is like `_.indexOf` except that it iterates over elements of
+`array` from right to left.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to search.
+2. `value` *(&#42;)*: The value to search for.
+3. `[fromIndex=array.length-1]` *(number)*: The index to search from.
+
+#### Returns
+*(number)*: Returns the index of the matched value, else `-1`.
+
+#### Example
+```js
+_.lastIndexOf([1, 2, 1, 2], 2);
+// => 3
+
+// Search from the `fromIndex`.
+_.lastIndexOf([1, 2, 1, 2], 2, 2);
+// => 1
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ntharray-n0"></a>`_.nth(array, [n=0])`
+<a href="#_ntharray-n0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6804 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.nth "See the npm package")
+
+Gets the nth element of `array`. If `n` is negative, the nth element
+from the end is returned.
+
+#### Since
+4.11.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[n=0]` *(number)*: The index of the element to return.
+
+#### Returns
+*(&#42;)*: Returns the nth element of `array`.
+
+#### Example
+```js
+var array = ['a', 'b', 'c', 'd'];
+
+_.nth(array, 1);
+// => 'b'
+
+_.nth(array, -2);
+// => 'c';
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pullarray-values"></a>`_.pull(array, [values])`
+<a href="#_pullarray-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6831 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pull "See the npm package")
+
+Removes all given values from `array` using
+[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons.
+<br>
+<br>
+**Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
+to remove elements from an array by predicate.
+
+#### Since
+2.0.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+2. `[values]` *(...&#42;)*: The values to remove.
+
+#### Returns
+*(Array)*: Returns `array`.
+
+#### Example
+```js
+var array = [1, 2, 3, 1, 2, 3];
+
+_.pull(array, 2, 3);
+console.log(array);
+// => [1, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pullallarray-values"></a>`_.pullAll(array, values)`
+<a href="#_pullallarray-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6853 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pullall "See the npm package")
+
+This method is like `_.pull` except that it accepts an array of values to remove.
+<br>
+<br>
+**Note:** Unlike `_.difference`, this method mutates `array`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+2. `values` *(Array)*: The values to remove.
+
+#### Returns
+*(Array)*: Returns `array`.
+
+#### Example
+```js
+var array = [1, 2, 3, 1, 2, 3];
+
+_.pullAll(array, [2, 3]);
+console.log(array);
+// => [1, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pullallbyarray-values-iteratee_identity"></a>`_.pullAllBy(array, values, [iteratee=_.identity])`
+<a href="#_pullallbyarray-values-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6883 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pullallby "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** Unlike `_.differenceBy`, this method mutates `array`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+2. `values` *(Array)*: The values to remove.
+3. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns `array`.
+
+#### Example
+```js
+var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+
+_.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
+console.log(array);
+// => [{ 'x': 2 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pullallwitharray-values-comparator"></a>`_.pullAllWith(array, values, [comparator])`
+<a href="#_pullallwitharray-values-comparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6912 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pullallwith "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** Unlike `_.differenceWith`, this method mutates `array`.
+
+#### Since
+4.6.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+2. `values` *(Array)*: The values to remove.
+3. `[comparator]` *(Function)*: The comparator invoked per element.
+
+#### Returns
+*(Array)*: Returns `array`.
+
+#### Example
+```js
+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 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pullatarray-indexes"></a>`_.pullAt(array, [indexes])`
+<a href="#_pullatarray-indexes">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6942 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pullat "See the npm package")
+
+Removes elements from `array` corresponding to `indexes` and returns an
+array of removed elements.
+<br>
+<br>
+**Note:** Unlike `_.at`, this method mutates `array`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+2. `[indexes]` *(...(number|number&#91;&#93;))*: The indexes of elements to remove.
+
+#### Returns
+*(Array)*: Returns the new array of removed elements.
+
+#### Example
+```js
+var array = [5, 10, 15, 20];
+var evens = _.pullAt(array, 1, 3);
+
+console.log(array);
+// => [5, 15]
+
+console.log(evens);
+// => [10, 20]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_removearray-predicate_identity"></a>`_.remove(array, [predicate=_.identity])`
+<a href="#_removearray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L6984 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.remove "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
+to pull elements from an array by value.
+
+#### Since
+2.0.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new array of removed elements.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_reversearray"></a>`_.reverse(array)`
+<a href="#_reversearray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7028 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.reverse "See the npm package")
+
+Reverses `array` so that the first element becomes the last, the second
+element becomes the second to last, and so on.
+<br>
+<br>
+**Note:** This method mutates `array` and is based on
+[`Array#reverse`](https://mdn.io/Array/reverse).
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to modify.
+
+#### Returns
+*(Array)*: Returns `array`.
+
+#### Example
+```js
+var array = [1, 2, 3];
+
+_.reverse(array);
+// => [3, 2, 1]
+
+console.log(array);
+// => [3, 2, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_slicearray-start0-endarraylength"></a>`_.slice(array, [start=0], [end=array.length])`
+<a href="#_slicearray-start0-endarraylength">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7048 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.slice "See the npm package")
+
+Creates a slice of `array` from `start` up to, but not including, `end`.
+<br>
+<br>
+**Note:** This method is used instead of
+[`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
+returned.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to slice.
+2. `[start=0]` *(number)*: The start position.
+3. `[end=array.length]` *(number)*: The end position.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortedindexarray-value"></a>`_.sortedIndex(array, value)`
+<a href="#_sortedindexarray-value">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7084 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortedindex "See the npm package")
+
+Uses a binary search to determine the lowest index at which `value`
+should be inserted into `array` in order to maintain its sort order.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The sorted array to inspect.
+2. `value` *(&#42;)*: The value to evaluate.
+
+#### Returns
+*(number)*: Returns the index at which `value` should be inserted into `array`.
+
+#### Example
+```js
+_.sortedIndex([30, 50], 40);
+// => 1
+
+_.sortedIndex([4, 5], 4);
+// => 0
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortedindexbyarray-value-iteratee_identity"></a>`_.sortedIndexBy(array, value, [iteratee=_.identity])`
+<a href="#_sortedindexbyarray-value-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7114 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortedindexby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The sorted array to inspect.
+2. `value` *(&#42;)*: The value to evaluate.
+3. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(number)*: Returns the index at which `value` should be inserted into `array`.
+
+#### Example
+```js
+var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
+
+_.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
+// => 1
+
+// The `_.property` iteratee shorthand.
+_.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+// => 0
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortedindexofarray-value"></a>`_.sortedIndexOf(array, value)`
+<a href="#_sortedindexofarray-value">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7134 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortedindexof "See the npm package")
+
+This method is like `_.indexOf` except that it performs a binary
+search on a sorted `array`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to search.
+2. `value` *(&#42;)*: The value to search for.
+
+#### Returns
+*(number)*: Returns the index of the matched value, else `-1`.
+
+#### Example
+```js
+_.sortedIndexOf([1, 1, 2, 2], 2);
+// => 2
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortedlastindexarray-value"></a>`_.sortedLastIndex(array, value)`
+<a href="#_sortedlastindexarray-value">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7163 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package")
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The sorted array to inspect.
+2. `value` *(&#42;)*: The value to evaluate.
+
+#### Returns
+*(number)*: Returns the index at which `value` should be inserted into `array`.
+
+#### Example
+```js
+_.sortedLastIndex([4, 5], 4);
+// => 1
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortedlastindexbyarray-value-iteratee_identity"></a>`_.sortedLastIndexBy(array, value, [iteratee=_.identity])`
+<a href="#_sortedlastindexbyarray-value-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7188 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortedlastindexby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The sorted array to inspect.
+2. `value` *(&#42;)*: The value to evaluate.
+3. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(number)*: Returns the index at which `value` should be inserted into `array`.
+
+#### Example
+```js
+// The `_.property` iteratee shorthand.
+_.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+// => 1
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortedlastindexofarray-value"></a>`_.sortedLastIndexOf(array, value)`
+<a href="#_sortedlastindexofarray-value">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7208 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortedlastindexof "See the npm package")
+
+This method is like `_.lastIndexOf` except that it performs a binary
+search on a sorted `array`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to search.
+2. `value` *(&#42;)*: The value to search for.
+
+#### Returns
+*(number)*: Returns the index of the matched value, else `-1`.
+
+#### Example
+```js
+_.sortedLastIndexOf([1, 1, 2, 2], 2);
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sorteduniqarray"></a>`_.sortedUniq(array)`
+<a href="#_sorteduniqarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7234 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sorteduniq "See the npm package")
+
+This method is like `_.uniq` except that it's designed and optimized
+for sorted arrays.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+
+#### Returns
+*(Array)*: Returns the new duplicate free array.
+
+#### Example
+```js
+_.sortedUniq([1, 1, 2]);
+// => [1, 2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sorteduniqbyarray-iteratee"></a>`_.sortedUniqBy(array, [iteratee])`
+<a href="#_sorteduniqbyarray-iteratee">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7256 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sorteduniqby "See the npm package")
+
+This method is like `_.uniqBy` except that it's designed and optimized
+for sorted arrays.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+2. `[iteratee]` *(Function)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns the new duplicate free array.
+
+#### Example
+```js
+_.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor);
+// => [1.1, 2.3]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tailarray"></a>`_.tail(array)`
+<a href="#_tailarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7276 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tail "See the npm package")
+
+Gets all but the first element of `array`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+_.tail([1, 2, 3]);
+// => [2, 3]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_takearray-n1"></a>`_.take(array, [n=1])`
+<a href="#_takearray-n1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7305 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.take "See the npm package")
+
+Creates a slice of `array` with `n` elements taken from the beginning.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[n=1]` *(number)*: The number of elements to take.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+_.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);
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_takerightarray-n1"></a>`_.takeRight(array, [n=1])`
+<a href="#_takerightarray-n1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7338 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.takeright "See the npm package")
+
+Creates a slice of `array` with `n` elements taken from the end.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[n=1]` *(number)*: The number of elements to take.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+_.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);
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_takerightwhilearray-predicate_identity"></a>`_.takeRightWhile(array, [predicate=_.identity])`
+<a href="#_takerightwhilearray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7384 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package")
+
+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)*.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+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');
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_takewhilearray-predicate_identity"></a>`_.takeWhile(array, [predicate=_.identity])`
+<a href="#_takewhilearray-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7426 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.takewhile "See the npm package")
+
+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)*.
+
+#### Since
+3.0.0
+#### Arguments
+1. `array` *(Array)*: The array to query.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the slice of `array`.
+
+#### Example
+```js
+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');
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unionarrays"></a>`_.union([arrays])`
+<a href="#_unionarrays">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7448 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.union "See the npm package")
+
+Creates an array of unique values, in order, from all given arrays using
+[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+
+#### Returns
+*(Array)*: Returns the new array of combined values.
+
+#### Example
+```js
+_.union([2, 1], [4, 2], [1, 2]);
+// => [2, 1, 4]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unionbyarrays-iteratee_identity"></a>`_.unionBy([arrays], [iteratee=_.identity])`
+<a href="#_unionbyarrays-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7475 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unionby "See the npm package")
+
+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. The iteratee is invoked with one argument:<br>
+*(value)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of combined values.
+
+#### Example
+```js
+_.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+// => [2.1, 1.2, 4.3]
+
+// The `_.property` iteratee shorthand.
+_.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+// => [{ 'x': 1 }, { 'x': 2 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unionwitharrays-comparator"></a>`_.unionWith([arrays], [comparator])`
+<a href="#_unionwitharrays-comparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7503 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unionwith "See the npm package")
+
+This method is like `_.union` except that it accepts `comparator` which
+is invoked to compare elements of `arrays`. The comparator is invoked
+with two arguments: *(arrVal, othVal)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+2. `[comparator]` *(Function)*: The comparator invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of combined values.
+
+#### Example
+```js
+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 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_uniqarray"></a>`_.uniq(array)`
+<a href="#_uniqarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7528 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.uniq "See the npm package")
+
+Creates a duplicate-free version of an array, using
+[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons, in which only the first occurrence of each
+element is kept.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+
+#### Returns
+*(Array)*: Returns the new duplicate free array.
+
+#### Example
+```js
+_.uniq([2, 1, 2]);
+// => [2, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_uniqbyarray-iteratee_identity"></a>`_.uniqBy(array, [iteratee=_.identity])`
+<a href="#_uniqbyarray-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7556 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.uniqby "See the npm package")
+
+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 iteratee is invoked with one argument: *(value)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns the new duplicate free array.
+
+#### Example
+```js
+_.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 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_uniqwitharray-comparator"></a>`_.uniqWith(array, [comparator])`
+<a href="#_uniqwitharray-comparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7581 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.uniqwith "See the npm package")
+
+This method is like `_.uniq` except that it accepts `comparator` which
+is invoked to compare elements of `array`. The comparator is invoked with
+two arguments: *(arrVal, othVal)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to inspect.
+2. `[comparator]` *(Function)*: The comparator invoked per element.
+
+#### Returns
+*(Array)*: Returns the new duplicate free array.
+
+#### Example
+```js
+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 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unziparray"></a>`_.unzip(array)`
+<a href="#_unziparray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7606 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unzip "See the npm package")
+
+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.
+
+#### Since
+1.2.0
+#### Arguments
+1. `array` *(Array)*: The array of grouped elements to process.
+
+#### Returns
+*(Array)*: Returns the new array of regrouped elements.
+
+#### Example
+```js
+var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
+// => [['fred', 30, true], ['barney', 40, false]]
+
+_.unzip(zipped);
+// => [['fred', 'barney'], [30, 40], [true, false]]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unzipwitharray-iteratee_identity"></a>`_.unzipWith(array, [iteratee=_.identity])`
+<a href="#_unzipwitharray-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7643 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unzipwith "See the npm package")
+
+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)*.
+
+#### Since
+3.8.0
+#### Arguments
+1. `array` *(Array)*: The array of grouped elements to process.
+2. `[iteratee=_.identity]` *(Function)*: The function to combine regrouped values.
+
+#### Returns
+*(Array)*: Returns the new array of regrouped elements.
+
+#### Example
+```js
+var zipped = _.zip([1, 2], [10, 20], [100, 200]);
+// => [[1, 10, 100], [2, 20, 200]]
+
+_.unzipWith(zipped, _.add);
+// => [3, 30, 300]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_withoutarray-values"></a>`_.without(array, [values])`
+<a href="#_withoutarray-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7674 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.without "See the npm package")
+
+Creates an array excluding all given values using
+[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+for equality comparisons.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to filter.
+2. `[values]` *(...&#42;)*: The values to exclude.
+
+#### Returns
+*(Array)*: Returns the new array of filtered values.
+
+#### Example
+```js
+_.without([1, 2, 1, 3], 1, 2);
+// => [3]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_xorarrays"></a>`_.xor([arrays])`
+<a href="#_xorarrays">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7698 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.xor "See the npm package")
+
+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.
+
+#### Since
+2.4.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+
+#### Returns
+*(Array)*: Returns the new array of values.
+
+#### Example
+```js
+_.xor([2, 1], [4, 2]);
+// => [1, 4]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_xorbyarrays-iteratee_identity"></a>`_.xorBy([arrays], [iteratee=_.identity])`
+<a href="#_xorbyarrays-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7725 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.xorby "See the npm package")
+
+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 iteratee is invoked with one argument:<br>
+*(value)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of values.
+
+#### Example
+```js
+_.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+// => [1.2, 4.3]
+
+// The `_.property` iteratee shorthand.
+_.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+// => [{ 'x': 2 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_xorwitharrays-comparator"></a>`_.xorWith([arrays], [comparator])`
+<a href="#_xorwitharrays-comparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7753 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.xorwith "See the npm package")
+
+This method is like `_.xor` except that it accepts `comparator` which is
+invoked to compare elements of `arrays`. The comparator is invoked with
+two arguments: *(arrVal, othVal)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to inspect.
+2. `[comparator]` *(Function)*: The comparator invoked per element.
+
+#### Returns
+*(Array)*: Returns the new array of values.
+
+#### Example
+```js
+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 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ziparrays"></a>`_.zip([arrays])`
+<a href="#_ziparrays">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7777 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.zip "See the npm package")
+
+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.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to process.
+
+#### Returns
+*(Array)*: Returns the new array of grouped elements.
+
+#### Example
+```js
+_.zip(['fred', 'barney'], [30, 40], [true, false]);
+// => [['fred', 30, true], ['barney', 40, false]]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_zipobjectprops-values"></a>`_.zipObject([props=[]], [values=[]])`
+<a href="#_zipobjectprops-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7795 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.zipobject "See the npm package")
+
+This method is like `_.fromPairs` except that it accepts two arrays,
+one of property identifiers and one of corresponding values.
+
+#### Since
+0.4.0
+#### Arguments
+1. `[props=[]]` *(Array)*: The property identifiers.
+2. `[values=[]]` *(Array)*: The property values.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+_.zipObject(['a', 'b'], [1, 2]);
+// => { 'a': 1, 'b': 2 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_zipobjectdeepprops-values"></a>`_.zipObjectDeep([props=[]], [values=[]])`
+<a href="#_zipobjectdeepprops-values">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7814 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.zipobjectdeep "See the npm package")
+
+This method is like `_.zipObject` except that it supports property paths.
+
+#### Since
+4.1.0
+#### Arguments
+1. `[props=[]]` *(Array)*: The property identifiers.
+2. `[values=[]]` *(Array)*: The property values.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+_.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
+// => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_zipwitharrays-iteratee_identity"></a>`_.zipWith([arrays], [iteratee=_.identity])`
+<a href="#_zipwitharrays-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7837 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.zipwith "See the npm package")
+
+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)*.
+
+#### Since
+3.8.0
+#### Arguments
+1. `[arrays]` *(...Array)*: The arrays to process.
+2. `[iteratee=_.identity]` *(Function)*: The function to combine grouped values.
+
+#### Returns
+*(Array)*: Returns the new array of grouped elements.
+
+#### Example
+```js
+_.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
+  return a + b + c;
+});
+// => [111, 222]
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Collection” Methods`
+
+<!-- div -->
+
+### <a id="_countbycollection-iteratee_identity"></a>`_.countBy(collection, [iteratee=_.identity])`
+<a href="#_countbycollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8220 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.countby "See the npm package")
+
+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)*.
+
+#### Since
+0.5.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee to transform keys.
+
+#### Returns
+*(Object)*: Returns the composed aggregate object.
+
+#### Example
+```js
+_.countBy([6.1, 4.2, 6.3], Math.floor);
+// => { '4': 1, '6': 2 }
+
+_.countBy(['one', 'two', 'three'], 'length');
+// => { '3': 2, '5': 1 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_everycollection-predicate_identity"></a>`_.every(collection, [predicate=_.identity])`
+<a href="#_everycollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8261 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.every "See the npm package")
+
+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)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(boolean)*: Returns `true` if all elements pass the predicate check, else `false`.
+
+#### Example
+```js
+_.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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_filtercollection-predicate_identity"></a>`_.filter(collection, [predicate=_.identity])`
+<a href="#_filtercollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8305 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.filter "See the npm package")
+
+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)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new filtered array.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_findcollection-predicate_identity"></a>`_.find(collection, [predicate=_.identity])`
+<a href="#_findcollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8346 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.find "See the npm package")
+
+Iterates over elements of `collection`, returning the first element
+`predicate` returns truthy for. The predicate is invoked with three
+arguments: *(value, index|key, collection)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to search.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(&#42;)*: Returns the matched element, else `undefined`.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_findlastcollection-predicate_identity"></a>`_.findLast(collection, [predicate=_.identity])`
+<a href="#_findlastcollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8374 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.findlast "See the npm package")
+
+This method is like `_.find` except that it iterates over elements of
+`collection` from right to left.
+
+#### Since
+2.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to search.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(&#42;)*: Returns the matched element, else `undefined`.
+
+#### Example
+```js
+_.findLast([1, 2, 3, 4], function(n) {
+  return n % 2 == 1;
+});
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flatmapcollection-iteratee_identity"></a>`_.flatMap(collection, [iteratee=_.identity])`
+<a href="#_flatmapcollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8405 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flatmap "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new flattened array.
+
+#### Example
+```js
+function duplicate(n) {
+  return [n, n];
+}
+
+_.flatMap([1, 2], duplicate);
+// => [1, 1, 2, 2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flatmapdeepcollection-iteratee_identity"></a>`_.flatMapDeep(collection, [iteratee=_.identity])`
+<a href="#_flatmapdeepcollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8430 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flatmapdeep "See the npm package")
+
+This method is like `_.flatMap` except that it recursively flattens the
+mapped results.
+
+#### Since
+4.7.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new flattened array.
+
+#### Example
+```js
+function duplicate(n) {
+  return [[[n, n]]];
+}
+
+_.flatMapDeep([1, 2], duplicate);
+// => [1, 1, 2, 2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flatmapdepthcollection-iteratee_identity-depth1"></a>`_.flatMapDepth(collection, [iteratee=_.identity], [depth=1])`
+<a href="#_flatmapdepthcollection-iteratee_identity-depth1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8456 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flatmapdepth "See the npm package")
+
+This method is like `_.flatMap` except that it recursively flattens the
+mapped results up to `depth` times.
+
+#### Since
+4.7.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+3. `[depth=1]` *(number)*: The maximum recursion depth.
+
+#### Returns
+*(Array)*: Returns the new flattened array.
+
+#### Example
+```js
+function duplicate(n) {
+  return [[[n, n]]];
+}
+
+_.flatMapDepth([1, 2], duplicate, 2);
+// => [[1, 1], [2, 2]]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_foreachcollection-iteratee_identity"></a>`_.forEach(collection, [iteratee=_.identity])`
+<a href="#_foreachcollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8491 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.foreach "See the npm package")
+
+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`.
+<br>
+<br>
+**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.
+
+#### Since
+0.1.0
+#### Aliases
+*_.each*
+
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(&#42;)*: Returns `collection`.
+
+#### Example
+```js
+_([1, 2]).forEach(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).
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_foreachrightcollection-iteratee_identity"></a>`_.forEachRight(collection, [iteratee=_.identity])`
+<a href="#_foreachrightcollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8517 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.foreachright "See the npm package")
+
+This method is like `_.forEach` except that it iterates over elements of
+`collection` from right to left.
+
+#### Since
+2.0.0
+#### Aliases
+*_.eachRight*
+
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(&#42;)*: Returns `collection`.
+
+#### Example
+```js
+_.forEachRight([1, 2], function(value) {
+  console.log(value);
+});
+// => Logs `2` then `1`.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_groupbycollection-iteratee_identity"></a>`_.groupBy(collection, [iteratee=_.identity])`
+<a href="#_groupbycollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8547 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.groupby "See the npm package")
+
+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)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee to transform keys.
+
+#### Returns
+*(Object)*: Returns the composed aggregate object.
+
+#### Example
+```js
+_.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'] }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_includescollection-value-fromindex0"></a>`_.includes(collection, value, [fromIndex=0])`
+<a href="#_includescollection-value-fromindex0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8585 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.includes "See the npm package")
+
+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/6.0/#sec-samevaluezero)
+is used for equality comparisons. If `fromIndex` is negative, it's used as
+the offset from the end of `collection`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object|string)*: The collection to search.
+2. `value` *(&#42;)*: The value to search for.
+3. `[fromIndex=0]` *(number)*: The index to search from.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is found, else `false`.
+
+#### Example
+```js
+_.includes([1, 2, 3], 1);
+// => true
+
+_.includes([1, 2, 3], 1, 2);
+// => false
+
+_.includes({ 'user': 'fred', 'age': 40 }, 'fred');
+// => true
+
+_.includes('pebbles', 'eb');
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_invokemapcollection-path-args"></a>`_.invokeMap(collection, path, [args])`
+<a href="#_invokemapcollection-path-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8621 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.invokemap "See the npm package")
+
+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 `methodName` is a function, it's
+invoked for and `this` bound to, each element in `collection`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `path` *(Array|Function|string)*: The path of the method to invoke or the function invoked per iteration.
+3. `[args]` *(...&#42;)*: The arguments to invoke each method with.
+
+#### Returns
+*(Array)*: Returns the array of results.
+
+#### Example
+```js
+_.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']]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_keybycollection-iteratee_identity"></a>`_.keyBy(collection, [iteratee=_.identity])`
+<a href="#_keybycollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8663 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.keyby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee to transform keys.
+
+#### Returns
+*(Object)*: Returns the composed aggregate object.
+
+#### Example
+```js
+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 } }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_mapcollection-iteratee_identity"></a>`_.map(collection, [iteratee=_.identity])`
+<a href="#_mapcollection-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8710 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.map "See the npm package")
+
+Creates an array of values by running each element in `collection` thru
+`iteratee`. The iteratee is invoked with three arguments:<br>
+*(value, index|key, collection)*.
+<br>
+<br>
+Many lodash methods are guarded to work as iteratees for methods like
+`_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
+<br>
+<br>
+The guarded methods are:<br>
+`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`
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new mapped array.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_orderbycollection-iteratees_identity-orders"></a>`_.orderBy(collection, [iteratees=[_.identity]], [orders])`
+<a href="#_orderbycollection-iteratees_identity-orders">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8744 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.orderby "See the npm package")
+
+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.
+
+#### Since
+4.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratees=[_.identity]]` *(Array&#91;&#93;|Function&#91;&#93;|Object&#91;&#93;|string&#91;&#93;)*: The iteratees to sort by.
+3. `[orders]` *(string&#91;&#93;)*: The sort orders of `iteratees`.
+
+#### Returns
+*(Array)*: Returns the new sorted array.
+
+#### Example
+```js
+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]]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_partitioncollection-predicate_identity"></a>`_.partition(collection, [predicate=_.identity])`
+<a href="#_partitioncollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8795 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.partition "See the npm package")
+
+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)*.
+
+#### Since
+3.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the array of grouped elements.
+
+#### Example
+```js
+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']]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_reducecollection-iteratee_identity-accumulator"></a>`_.reduce(collection, [iteratee=_.identity], [accumulator])`
+<a href="#_reducecollection-iteratee_identity-accumulator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8836 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.reduce "See the npm package")
+
+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:<br>
+*(accumulator, value, index|key, collection)*.
+<br>
+<br>
+Many lodash methods are guarded to work as iteratees for methods like
+`_.reduce`, `_.reduceRight`, and `_.transform`.
+<br>
+<br>
+The guarded methods are:<br>
+`assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
+and `sortBy`
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+3. `[accumulator]` *(&#42;)*: The initial value.
+
+#### Returns
+*(&#42;)*: Returns the accumulated value.
+
+#### Example
+```js
+_.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)
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_reducerightcollection-iteratee_identity-accumulator"></a>`_.reduceRight(collection, [iteratee=_.identity], [accumulator])`
+<a href="#_reducerightcollection-iteratee_identity-accumulator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8865 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.reduceright "See the npm package")
+
+This method is like `_.reduce` except that it iterates over elements of
+`collection` from right to left.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+3. `[accumulator]` *(&#42;)*: The initial value.
+
+#### Returns
+*(&#42;)*: Returns the accumulated value.
+
+#### Example
+```js
+var array = [[0, 1], [2, 3], [4, 5]];
+
+_.reduceRight(array, function(flattened, other) {
+  return flattened.concat(other);
+}, []);
+// => [4, 5, 2, 3, 0, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_rejectcollection-predicate_identity"></a>`_.reject(collection, [predicate=_.identity])`
+<a href="#_rejectcollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8907 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.reject "See the npm package")
+
+The opposite of `_.filter`; this method returns the elements of `collection`
+that `predicate` does **not** return truthy for.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the new filtered array.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_samplecollection"></a>`_.sample(collection)`
+<a href="#_samplecollection">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8929 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sample "See the npm package")
+
+Gets a random element from `collection`.
+
+#### Since
+2.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to sample.
+
+#### Returns
+*(&#42;)*: Returns the random element.
+
+#### Example
+```js
+_.sample([1, 2, 3, 4]);
+// => 2
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_samplesizecollection-n1"></a>`_.sampleSize(collection, [n=1])`
+<a href="#_samplesizecollection-n1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8956 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.samplesize "See the npm package")
+
+Gets `n` random elements at unique keys from `collection` up to the
+size of `collection`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to sample.
+2. `[n=1]` *(number)*: The number of elements to sample.
+
+#### Returns
+*(Array)*: Returns the random elements.
+
+#### Example
+```js
+_.sampleSize([1, 2, 3], 2);
+// => [3, 1]
+
+_.sampleSize([1, 2, 3], 4);
+// => [2, 3, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_shufflecollection"></a>`_.shuffle(collection)`
+<a href="#_shufflecollection">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8993 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.shuffle "See the npm package")
+
+Creates an array of shuffled values, using a version of the
+[Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to shuffle.
+
+#### Returns
+*(Array)*: Returns the new shuffled array.
+
+#### Example
+```js
+_.shuffle([1, 2, 3, 4]);
+// => [4, 1, 3, 2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sizecollection"></a>`_.size(collection)`
+<a href="#_sizecollection">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9018 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.size "See the npm package")
+
+Gets the size of `collection` by returning its length for array-like
+values or the number of own enumerable string keyed properties for objects.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to inspect.
+
+#### Returns
+*(number)*: Returns the collection size.
+
+#### Example
+```js
+_.size([1, 2, 3]);
+// => 3
+
+_.size({ 'a': 1, 'b': 2 });
+// => 2
+
+_.size('pebbles');
+// => 7
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_somecollection-predicate_identity"></a>`_.some(collection, [predicate=_.identity])`
+<a href="#_somecollection-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9072 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.some "See the npm package")
+
+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)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(boolean)*: Returns `true` if any element passes the predicate check, else `false`.
+
+#### Example
+```js
+_.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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sortbycollection-iteratees_identity"></a>`_.sortBy(collection, [iteratees=[_.identity]])`
+<a href="#_sortbycollection-iteratees_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9114 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sortby "See the npm package")
+
+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)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `collection` *(Array|Object)*: The collection to iterate over.
+2. `[iteratees=[_.identity]]` *(...(Array|Array&#91;&#93;|Function|Function&#91;&#93;|Object|Object&#91;&#93;|string|string&#91;&#93;))*: The iteratees to sort by.
+
+#### Returns
+*(Array)*: Returns the new sorted array.
+
+#### Example
+```js
+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]]
+
+_.sortBy(users, 'user', function(o) {
+  return Math.floor(o.age / 10);
+});
+// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Date” Methods`
+
+<!-- div -->
+
+### <a id="_now"></a>`_.now()`
+<a href="#_now">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9150 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.now "See the npm package")
+
+Gets the timestamp of the number of milliseconds that have elapsed since
+the Unix epoch *(1 January `1970 00`:00:00 UTC)*.
+
+#### Since
+2.4.0
+#### Returns
+*(number)*: Returns the timestamp.
+
+#### Example
+```js
+_.defer(function(stamp) {
+  console.log(_.now() - stamp);
+}, _.now());
+// => Logs the number of milliseconds it took for the deferred function to be invoked.
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Function” Methods`
+
+<!-- div -->
+
+### <a id="_aftern-func"></a>`_.after(n, func)`
+<a href="#_aftern-func">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9178 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.after "See the npm package")
+
+The opposite of `_.before`; this method creates a function that invokes
+`func` once it's called `n` or more times.
+
+#### Since
+0.1.0
+#### Arguments
+1. `n` *(number)*: The number of calls before `func` is invoked.
+2. `func` *(Function)*: The function to restrict.
+
+#### Returns
+*(Function)*: Returns the new restricted function.
+
+#### Example
+```js
+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.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_aryfunc-nfunclength"></a>`_.ary(func, [n=func.length])`
+<a href="#_aryfunc-nfunclength">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9207 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.ary "See the npm package")
+
+Creates a function that invokes `func`, with up to `n` arguments,
+ignoring any additional arguments.
+
+#### Since
+3.0.0
+#### Arguments
+1. `func` *(Function)*: The function to cap arguments for.
+2. `[n=func.length]` *(number)*: The arity cap.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+_.map(['6', '8', '10'], _.ary(parseInt, 1));
+// => [6, 8, 10]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_beforen-func"></a>`_.before(n, func)`
+<a href="#_beforen-func">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9230 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.before "See the npm package")
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `n` *(number)*: The number of calls at which `func` is no longer invoked.
+2. `func` *(Function)*: The function to restrict.
+
+#### Returns
+*(Function)*: Returns the new restricted function.
+
+#### Example
+```js
+jQuery(element).on('click', _.before(5, addContactToList));
+// => allows adding up to 4 contacts to the list
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_bindfunc-thisarg-partials"></a>`_.bind(func, thisArg, [partials])`
+<a href="#_bindfunc-thisarg-partials">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9282 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.bind "See the npm package")
+
+Creates a function that invokes `func` with the `this` binding of `thisArg`
+and `partials` prepended to the arguments it receives.
+<br>
+<br>
+The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
+may be used as a placeholder for partially applied arguments.
+<br>
+<br>
+**Note:** Unlike native `Function#bind` this method doesn't set the "length"
+property of bound functions.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to bind.
+2. `thisArg` *(&#42;)*: The `this` binding of `func`.
+3. `[partials]` *(...&#42;)*: The arguments to be partially applied.
+
+#### Returns
+*(Function)*: Returns the new bound function.
+
+#### Example
+```js
+var greet = function(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!'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_bindkeyobject-key-partials"></a>`_.bindKey(object, key, [partials])`
+<a href="#_bindkeyobject-key-partials">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9336 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.bindkey "See the npm package")
+
+Creates a function that invokes the method at `object[key]` with `partials`
+prepended to the arguments it receives.
+<br>
+<br>
+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.
+<br>
+<br>
+The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
+builds, may be used as a placeholder for partially applied arguments.
+
+#### Since
+0.10.0
+#### Arguments
+1. `object` *(Object)*: The object to invoke the method on.
+2. `key` *(string)*: The key of the method.
+3. `[partials]` *(...&#42;)*: The arguments to be partially applied.
+
+#### Returns
+*(Function)*: Returns the new bound function.
+
+#### Example
+```js
+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!'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_curryfunc-arityfunclength"></a>`_.curry(func, [arity=func.length])`
+<a href="#_curryfunc-arityfunclength">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9386 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.curry "See the npm package")
+
+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.
+<br>
+<br>
+The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
+may be used as a placeholder for provided arguments.
+<br>
+<br>
+**Note:** This method doesn't set the "length" property of curried functions.
+
+#### Since
+2.0.0
+#### Arguments
+1. `func` *(Function)*: The function to curry.
+2. `[arity=func.length]` *(number)*: The arity of `func`.
+
+#### Returns
+*(Function)*: Returns the new curried function.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_curryrightfunc-arityfunclength"></a>`_.curryRight(func, [arity=func.length])`
+<a href="#_curryrightfunc-arityfunclength">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9431 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.curryright "See the npm package")
+
+This method is like `_.curry` except that arguments are applied to `func`
+in the manner of `_.partialRight` instead of `_.partial`.
+<br>
+<br>
+The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
+builds, may be used as a placeholder for provided arguments.
+<br>
+<br>
+**Note:** This method doesn't set the "length" property of curried functions.
+
+#### Since
+3.0.0
+#### Arguments
+1. `func` *(Function)*: The function to curry.
+2. `[arity=func.length]` *(number)*: The arity of `func`.
+
+#### Returns
+*(Function)*: Returns the new curried function.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_debouncefunc-wait0-options-optionsleadingfalse-optionsmaxwait-optionstrailingtrue"></a>`_.debounce(func, [wait=0], [options={}], [options.leading=false], [options.maxWait], [options.trailing=true])`
+<a href="#_debouncefunc-wait0-options-optionsleadingfalse-optionsmaxwait-optionstrailingtrue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9488 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.debounce "See the npm package")
+
+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 an options object 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.
+<br>
+<br>
+**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.
+<br>
+<br>
+See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+for details over the differences between `_.debounce` and `_.throttle`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to debounce.
+2. `[wait=0]` *(number)*: The number of milliseconds to delay.
+3. `[options={}]` *(Object)*: The options object.
+4. `[options.leading=false]` *(boolean)*: Specify invoking on the leading edge of the timeout.
+5. `[options.maxWait]` *(number)*: The maximum time `func` is allowed to be delayed before it's invoked.
+6. `[options.trailing=true]` *(boolean)*: Specify invoking on the trailing edge of the timeout.
+
+#### Returns
+*(Function)*: Returns the new debounced function.
+
+#### Example
+```js
+// 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);
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_deferfunc-args"></a>`_.defer(func, [args])`
+<a href="#_deferfunc-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9630 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.defer "See the npm package")
+
+Defers invoking the `func` until the current call stack has cleared. Any
+additional arguments are provided to `func` when it's invoked.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to defer.
+2. `[args]` *(...&#42;)*: The arguments to invoke `func` with.
+
+#### Returns
+*(number)*: Returns the timer id.
+
+#### Example
+```js
+_.defer(function(text) {
+  console.log(text);
+}, 'deferred');
+// => Logs 'deferred' after one or more milliseconds.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_delayfunc-wait-args"></a>`_.delay(func, wait, [args])`
+<a href="#_delayfunc-wait-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9653 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.delay "See the npm package")
+
+Invokes `func` after `wait` milliseconds. Any additional arguments are
+provided to `func` when it's invoked.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to delay.
+2. `wait` *(number)*: The number of milliseconds to delay invocation.
+3. `[args]` *(...&#42;)*: The arguments to invoke `func` with.
+
+#### Returns
+*(number)*: Returns the timer id.
+
+#### Example
+```js
+_.delay(function(text) {
+  console.log(text);
+}, 1000, 'later');
+// => Logs 'later' after one second.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flipfunc"></a>`_.flip(func)`
+<a href="#_flipfunc">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9675 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flip "See the npm package")
+
+Creates a function that invokes `func` with arguments reversed.
+
+#### Since
+4.0.0
+#### Arguments
+1. `func` *(Function)*: The function to flip arguments for.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var flipped = _.flip(function() {
+  return _.toArray(arguments);
+});
+
+flipped('a', 'b', 'c', 'd');
+// => ['d', 'c', 'b', 'a']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_memoizefunc-resolver"></a>`_.memoize(func, [resolver])`
+<a href="#_memoizefunc-resolver">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9723 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.memoize "See the npm package")
+
+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.
+<br>
+<br>
+**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/6.0/#sec-properties-of-the-map-prototype-object)
+method interface of `delete`, `get`, `has`, and `set`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to have its output memoized.
+2. `[resolver]` *(Function)*: The function to resolve the cache key.
+
+#### Returns
+*(Function)*: Returns the new memoizing function.
+
+#### Example
+```js
+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;
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_negatepredicate"></a>`_.negate(predicate)`
+<a href="#_negatepredicate">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9766 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.negate "See the npm package")
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `predicate` *(Function)*: The predicate to negate.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+function isEven(n) {
+  return n % 2 == 0;
+}
+
+_.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
+// => [1, 3, 5]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_oncefunc"></a>`_.once(func)`
+<a href="#_oncefunc">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9793 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.once "See the npm package")
+
+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.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to restrict.
+
+#### Returns
+*(Function)*: Returns the new restricted function.
+
+#### Example
+```js
+var initialize = _.once(createApplication);
+initialize();
+initialize();
+// `initialize` invokes `createApplication` once
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_overargsfunc"></a>`_.overArgs(func)`
+<a href="#_overargsfunc">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9829 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.overargs "See the npm package")
+
+Creates a function that invokes `func` with arguments transformed by
+corresponding `transforms`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `func` *(Function)*: The function to wrap.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_partialfunc-partials"></a>`_.partial(func, [partials])`
+<a href="#_partialfunc-partials">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9879 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.partial "See the npm package")
+
+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.
+<br>
+<br>
+The `_.partial.placeholder` value, which defaults to `_` in monolithic
+builds, may be used as a placeholder for partially applied arguments.
+<br>
+<br>
+**Note:** This method doesn't set the "length" property of partially
+applied functions.
+
+#### Since
+0.2.0
+#### Arguments
+1. `func` *(Function)*: The function to partially apply arguments to.
+2. `[partials]` *(...&#42;)*: The arguments to be partially applied.
+
+#### Returns
+*(Function)*: Returns the new partially applied function.
+
+#### Example
+```js
+var greet = function(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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_partialrightfunc-partials"></a>`_.partialRight(func, [partials])`
+<a href="#_partialrightfunc-partials">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9916 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.partialright "See the npm package")
+
+This method is like `_.partial` except that partially applied arguments
+are appended to the arguments it receives.
+<br>
+<br>
+The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
+builds, may be used as a placeholder for partially applied arguments.
+<br>
+<br>
+**Note:** This method doesn't set the "length" property of partially
+applied functions.
+
+#### Since
+1.0.0
+#### Arguments
+1. `func` *(Function)*: The function to partially apply arguments to.
+2. `[partials]` *(...&#42;)*: The arguments to be partially applied.
+
+#### Returns
+*(Function)*: Returns the new partially applied function.
+
+#### Example
+```js
+var greet = function(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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_reargfunc-indexes"></a>`_.rearg(func, indexes)`
+<a href="#_reargfunc-indexes">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9943 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.rearg "See the npm package")
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `func` *(Function)*: The function to rearrange arguments for.
+2. `indexes` *(...(number|number&#91;&#93;))*: The arranged argument indexes.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var rearged = _.rearg(function(a, b, c) {
+  return [a, b, c];
+}, 2, 0, 1);
+
+rearged('b', 'c', 'a')
+// => ['a', 'b', 'c']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_restfunc-startfunclength-1"></a>`_.rest(func, [start=func.length-1])`
+<a href="#_restfunc-startfunclength-1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L9972 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.rest "See the npm package")
+
+Creates a function that invokes `func` with the `this` binding of the
+created function and arguments from `start` and beyond provided as
+an array.
+<br>
+<br>
+**Note:** This method is based on the
+[rest parameter](https://mdn.io/rest_parameters).
+
+#### Since
+4.0.0
+#### Arguments
+1. `func` *(Function)*: The function to apply a rest parameter to.
+2. `[start=func.length-1]` *(number)*: The start position of the rest parameter.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_spreadfunc-start0"></a>`_.spread(func, [start=0])`
+<a href="#_spreadfunc-start0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10035 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.spread "See the npm package")
+
+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/6.0/#sec-function.prototype.apply).
+<br>
+<br>
+**Note:** This method is based on the
+[spread operator](https://mdn.io/spread_operator).
+
+#### Since
+3.2.0
+#### Arguments
+1. `func` *(Function)*: The function to spread arguments over.
+2. `[start=0]` *(number)*: The start position of the spread.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_throttlefunc-wait0-options-optionsleadingtrue-optionstrailingtrue"></a>`_.throttle(func, [wait=0], [options={}], [options.leading=true], [options.trailing=true])`
+<a href="#_throttlefunc-wait0-options-optionsleadingtrue-optionstrailingtrue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10092 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.throttle "See the npm package")
+
+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 an options object 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.
+<br>
+<br>
+**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.
+<br>
+<br>
+See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+for details over the differences between `_.throttle` and `_.debounce`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `func` *(Function)*: The function to throttle.
+2. `[wait=0]` *(number)*: The number of milliseconds to throttle invocations to.
+3. `[options={}]` *(Object)*: The options object.
+4. `[options.leading=true]` *(boolean)*: Specify invoking on the leading edge of the timeout.
+5. `[options.trailing=true]` *(boolean)*: Specify invoking on the trailing edge of the timeout.
+
+#### Returns
+*(Function)*: Returns the new throttled function.
+
+#### Example
+```js
+// 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);
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unaryfunc"></a>`_.unary(func)`
+<a href="#_unaryfunc">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10125 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unary "See the npm package")
+
+Creates a function that accepts up to one argument, ignoring any
+additional arguments.
+
+#### Since
+4.0.0
+#### Arguments
+1. `func` *(Function)*: The function to cap arguments for.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+_.map(['6', '8', '10'], _.unary(parseInt));
+// => [6, 8, 10]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_wrapvalue-wrapperidentity"></a>`_.wrap(value, [wrapper=identity])`
+<a href="#_wrapvalue-wrapperidentity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10151 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.wrap "See the npm package")
+
+Creates a function that provides `value` to the wrapper function as its
+first argument. Any additional arguments provided to the function are
+appended to those provided to the wrapper function. The wrapper is invoked
+with the `this` binding of the created function.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to wrap.
+2. `[wrapper=identity]` *(Function)*: The wrapper function.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var p = _.wrap(_.escape, function(func, text) {
+  return '<p>' + func(text) + '</p>';
+});
+
+p('fred, barney, & pebbles');
+// => '<p>fred, barney, &amp; pebbles</p>'
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Lang” Methods`
+
+<!-- div -->
+
+### <a id="_castarrayvalue"></a>`_.castArray(value)`
+<a href="#_castarrayvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10191 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.castarray "See the npm package")
+
+Casts `value` as an array if it's not one.
+
+#### Since
+4.4.0
+#### Arguments
+1. `value` *(&#42;)*: The value to inspect.
+
+#### Returns
+*(Array)*: Returns the cast array.
+
+#### Example
+```js
+_.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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_clonevalue"></a>`_.clone(value)`
+<a href="#_clonevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10225 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.clone "See the npm package")
+
+Creates a shallow clone of `value`.
+<br>
+<br>
+**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.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to clone.
+
+#### Returns
+*(&#42;)*: Returns the cloned value.
+
+#### Example
+```js
+var objects = [{ 'a': 1 }, { 'b': 2 }];
+
+var shallow = _.clone(objects);
+console.log(shallow[0] === objects[0]);
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_clonedeepvalue"></a>`_.cloneDeep(value)`
+<a href="#_clonedeepvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10282 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.clonedeep "See the npm package")
+
+This method is like `_.clone` except that it recursively clones `value`.
+
+#### Since
+1.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to recursively clone.
+
+#### Returns
+*(&#42;)*: Returns the deep cloned value.
+
+#### Example
+```js
+var objects = [{ 'a': 1 }, { 'b': 2 }];
+
+var deep = _.cloneDeep(objects);
+console.log(deep[0] === objects[0]);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_clonedeepwithvalue-customizer"></a>`_.cloneDeepWith(value, [customizer])`
+<a href="#_clonedeepwithvalue-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10314 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.clonedeepwith "See the npm package")
+
+This method is like `_.cloneWith` except that it recursively clones `value`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to recursively clone.
+2. `[customizer]` *(Function)*: The function to customize cloning.
+
+#### Returns
+*(&#42;)*: Returns the deep cloned value.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_clonewithvalue-customizer"></a>`_.cloneWith(value, [customizer])`
+<a href="#_clonewithvalue-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10260 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.clonewith "See the npm package")
+
+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])*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to clone.
+2. `[customizer]` *(Function)*: The function to customize cloning.
+
+#### Returns
+*(&#42;)*: Returns the cloned value.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_eqvalue-other"></a>`_.eq(value, other)`
+<a href="#_eqvalue-other">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10350 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.eq "See the npm package")
+
+Performs a
+[`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+comparison between two values to determine if they are equivalent.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+
+#### Returns
+*(boolean)*: Returns `true` if the values are equivalent, else `false`.
+
+#### Example
+```js
+var object = { 'user': 'fred' };
+var other = { 'user': 'fred' };
+
+_.eq(object, object);
+// => true
+
+_.eq(object, other);
+// => false
+
+_.eq('a', 'a');
+// => true
+
+_.eq('a', Object('a'));
+// => false
+
+_.eq(NaN, NaN);
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_gtvalue-other"></a>`_.gt(value, other)`
+<a href="#_gtvalue-other">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10377 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.gt "See the npm package")
+
+Checks if `value` is greater than `other`.
+
+#### Since
+3.9.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is greater than `other`, else `false`.
+
+#### Example
+```js
+_.gt(3, 1);
+// => true
+
+_.gt(3, 3);
+// => false
+
+_.gt(1, 3);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_gtevalue-other"></a>`_.gte(value, other)`
+<a href="#_gtevalue-other">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10402 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.gte "See the npm package")
+
+Checks if `value` is greater than or equal to `other`.
+
+#### Since
+3.9.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is greater than or equal to `other`, else `false`.
+
+#### Example
+```js
+_.gte(3, 1);
+// => true
+
+_.gte(3, 3);
+// => true
+
+_.gte(1, 3);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isargumentsvalue"></a>`_.isArguments(value)`
+<a href="#_isargumentsvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10424 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isarguments "See the npm package")
+
+Checks if `value` is likely an `arguments` object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isArguments(function() { return arguments; }());
+// => true
+
+_.isArguments([1, 2, 3]);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isarrayvalue"></a>`_.isArray(value)`
+<a href="#_isarrayvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10455 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isarray "See the npm package")
+
+Checks if `value` is classified as an `Array` object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isArray([1, 2, 3]);
+// => true
+
+_.isArray(document.body.children);
+// => false
+
+_.isArray('abc');
+// => false
+
+_.isArray(_.noop);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isarraybuffervalue"></a>`_.isArrayBuffer(value)`
+<a href="#_isarraybuffervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10475 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isarraybuffer "See the npm package")
+
+Checks if `value` is classified as an `ArrayBuffer` object.
+
+#### Since
+4.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isArrayBuffer(new ArrayBuffer(2));
+// => true
+
+_.isArrayBuffer(new Array(2));
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isarraylikevalue"></a>`_.isArrayLike(value)`
+<a href="#_isarraylikevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10504 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isarraylike "See the npm package")
+
+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`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is array-like, else `false`.
+
+#### Example
+```js
+_.isArrayLike([1, 2, 3]);
+// => true
+
+_.isArrayLike(document.body.children);
+// => true
+
+_.isArrayLike('abc');
+// => true
+
+_.isArrayLike(_.noop);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isarraylikeobjectvalue"></a>`_.isArrayLikeObject(value)`
+<a href="#_isarraylikeobjectvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10533 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isarraylikeobject "See the npm package")
+
+This method is like `_.isArrayLike` except that it also checks if `value`
+is an object.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is an array-like object, else `false`.
+
+#### Example
+```js
+_.isArrayLikeObject([1, 2, 3]);
+// => true
+
+_.isArrayLikeObject(document.body.children);
+// => true
+
+_.isArrayLikeObject('abc');
+// => false
+
+_.isArrayLikeObject(_.noop);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isbooleanvalue"></a>`_.isBoolean(value)`
+<a href="#_isbooleanvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10555 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isboolean "See the npm package")
+
+Checks if `value` is classified as a boolean primitive or object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isBoolean(false);
+// => true
+
+_.isBoolean(null);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isbuffervalue"></a>`_.isBuffer(value)`
+<a href="#_isbuffervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10577 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isbuffer "See the npm package")
+
+Checks if `value` is a buffer.
+
+#### Since
+4.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a buffer, else `false`.
+
+#### Example
+```js
+_.isBuffer(new Buffer(2));
+// => true
+
+_.isBuffer(new Uint8Array(2));
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isdatevalue"></a>`_.isDate(value)`
+<a href="#_isdatevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10599 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isdate "See the npm package")
+
+Checks if `value` is classified as a `Date` object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isDate(new Date);
+// => true
+
+_.isDate('Mon April 23 2012');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_iselementvalue"></a>`_.isElement(value)`
+<a href="#_iselementvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10621 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.iselement "See the npm package")
+
+Checks if `value` is likely a DOM element.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a DOM element, else `false`.
+
+#### Example
+```js
+_.isElement(document.body);
+// => true
+
+_.isElement('<body>');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isemptyvalue"></a>`_.isEmpty(value)`
+<a href="#_isemptyvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10658 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isempty "See the npm package")
+
+Checks if `value` is an empty object, collection, map, or set.
+<br>
+<br>
+Objects are considered empty if they have no own enumerable string keyed
+properties.
+<br>
+<br>
+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`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is empty, else `false`.
+
+#### Example
+```js
+_.isEmpty(null);
+// => true
+
+_.isEmpty(true);
+// => true
+
+_.isEmpty(1);
+// => true
+
+_.isEmpty([1, 2, 3]);
+// => false
+
+_.isEmpty({ 'a': 1 });
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isequalvalue-other"></a>`_.isEqual(value, other)`
+<a href="#_isequalvalue-other">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10707 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isequal "See the npm package")
+
+Performs a deep comparison between two values to determine if they are
+equivalent.
+<br>
+<br>
+**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 **not** supported.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+
+#### Returns
+*(boolean)*: Returns `true` if the values are equivalent, else `false`.
+
+#### Example
+```js
+var object = { 'user': 'fred' };
+var other = { 'user': 'fred' };
+
+_.isEqual(object, other);
+// => true
+
+object === other;
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isequalwithvalue-other-customizer"></a>`_.isEqualWith(value, other, [customizer])`
+<a href="#_isequalwithvalue-other-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10744 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isequalwith "See the npm package")
+
+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])*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+3. `[customizer]` *(Function)*: The function to customize comparisons.
+
+#### Returns
+*(boolean)*: Returns `true` if the values are equivalent, else `false`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_iserrorvalue"></a>`_.isError(value)`
+<a href="#_iserrorvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10769 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.iserror "See the npm package")
+
+Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
+`SyntaxError`, `TypeError`, or `URIError` object.
+
+#### Since
+3.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is an error object, else `false`.
+
+#### Example
+```js
+_.isError(new Error);
+// => true
+
+_.isError(Error);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isfinitevalue"></a>`_.isFinite(value)`
+<a href="#_isfinitevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10804 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isfinite "See the npm package")
+
+Checks if `value` is a finite primitive number.
+<br>
+<br>
+**Note:** This method is based on
+[`Number.isFinite`](https://mdn.io/Number/isFinite).
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a finite number, else `false`.
+
+#### Example
+```js
+_.isFinite(3);
+// => true
+
+_.isFinite(Number.MAX_VALUE);
+// => true
+
+_.isFinite(3.14);
+// => true
+
+_.isFinite(Infinity);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isfunctionvalue"></a>`_.isFunction(value)`
+<a href="#_isfunctionvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10826 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isfunction "See the npm package")
+
+Checks if `value` is classified as a `Function` object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isFunction(_);
+// => true
+
+_.isFunction(/abc/);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isintegervalue"></a>`_.isInteger(value)`
+<a href="#_isintegervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10860 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isinteger "See the npm package")
+
+Checks if `value` is an integer.
+<br>
+<br>
+**Note:** This method is based on
+[`Number.isInteger`](https://mdn.io/Number/isInteger).
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is an integer, else `false`.
+
+#### Example
+```js
+_.isInteger(3);
+// => true
+
+_.isInteger(Number.MIN_VALUE);
+// => false
+
+_.isInteger(Infinity);
+// => false
+
+_.isInteger('3');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_islengthvalue"></a>`_.isLength(value)`
+<a href="#_islengthvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10891 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.islength "See the npm package")
+
+Checks if `value` is a valid array-like length.
+<br>
+<br>
+**Note:** This function is loosely based on
+[`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a valid length, else `false`.
+
+#### Example
+```js
+_.isLength(3);
+// => true
+
+_.isLength(Number.MIN_VALUE);
+// => false
+
+_.isLength(Infinity);
+// => false
+
+_.isLength('3');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ismapvalue"></a>`_.isMap(value)`
+<a href="#_ismapvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10972 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.ismap "See the npm package")
+
+Checks if `value` is classified as a `Map` object.
+
+#### Since
+4.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isMap(new Map);
+// => true
+
+_.isMap(new WeakMap);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ismatchobject-source"></a>`_.isMatch(object, source)`
+<a href="#_ismatchobject-source">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11000 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.ismatch "See the npm package")
+
+Performs a partial deep comparison between `object` and `source` to
+determine if `object` contains equivalent property values. This method is
+equivalent to a `_.matches` function when `source` is partially applied.
+<br>
+<br>
+**Note:** This method supports comparing the same values as `_.isEqual`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `object` *(Object)*: The object to inspect.
+2. `source` *(Object)*: The object of property values to match.
+
+#### Returns
+*(boolean)*: Returns `true` if `object` is a match, else `false`.
+
+#### Example
+```js
+var object = { 'user': 'fred', 'age': 40 };
+
+_.isMatch(object, { 'age': 40 });
+// => true
+
+_.isMatch(object, { 'age': 36 });
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ismatchwithobject-source-customizer"></a>`_.isMatchWith(object, source, [customizer])`
+<a href="#_ismatchwithobject-source-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11036 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.ismatchwith "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The object to inspect.
+2. `source` *(Object)*: The object of property values to match.
+3. `[customizer]` *(Function)*: The function to customize comparisons.
+
+#### Returns
+*(boolean)*: Returns `true` if `object` is a match, else `false`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isnanvalue"></a>`_.isNaN(value)`
+<a href="#_isnanvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11069 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isnan "See the npm package")
+
+Checks if `value` is `NaN`.
+<br>
+<br>
+**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.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is `NaN`, else `false`.
+
+#### Example
+```js
+_.isNaN(NaN);
+// => true
+
+_.isNaN(new Number(NaN));
+// => true
+
+isNaN(undefined);
+// => true
+
+_.isNaN(undefined);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isnativevalue"></a>`_.isNative(value)`
+<a href="#_isnativevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11094 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isnative "See the npm package")
+
+Checks if `value` is a native function.
+
+#### Since
+3.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a native function, else `false`.
+
+#### Example
+```js
+_.isNative(Array.prototype.push);
+// => true
+
+_.isNative(_);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isnilvalue"></a>`_.isNil(value)`
+<a href="#_isnilvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11143 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isnil "See the npm package")
+
+Checks if `value` is `null` or `undefined`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is nullish, else `false`.
+
+#### Example
+```js
+_.isNil(null);
+// => true
+
+_.isNil(void 0);
+// => true
+
+_.isNil(NaN);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isnullvalue"></a>`_.isNull(value)`
+<a href="#_isnullvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11119 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isnull "See the npm package")
+
+Checks if `value` is `null`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is `null`, else `false`.
+
+#### Example
+```js
+_.isNull(null);
+// => true
+
+_.isNull(void 0);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isnumbervalue"></a>`_.isNumber(value)`
+<a href="#_isnumbervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11174 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isnumber "See the npm package")
+
+Checks if `value` is classified as a `Number` primitive or object.
+<br>
+<br>
+**Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
+classified as numbers, use the `_.isFinite` method.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isNumber(3);
+// => true
+
+_.isNumber(Number.MIN_VALUE);
+// => true
+
+_.isNumber(Infinity);
+// => true
+
+_.isNumber('3');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isobjectvalue"></a>`_.isObject(value)`
+<a href="#_isobjectvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10921 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isobject "See the npm package")
+
+Checks if `value` is the
+[language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
+of `Object`. *(e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)*
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is an object, else `false`.
+
+#### Example
+```js
+_.isObject({});
+// => true
+
+_.isObject([1, 2, 3]);
+// => true
+
+_.isObject(_.noop);
+// => true
+
+_.isObject(null);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isobjectlikevalue"></a>`_.isObjectLike(value)`
+<a href="#_isobjectlikevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L10950 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isobjectlike "See the npm package")
+
+Checks if `value` is object-like. A value is object-like if it's not `null`
+and has a `typeof` result of "object".
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is object-like, else `false`.
+
+#### Example
+```js
+_.isObjectLike({});
+// => true
+
+_.isObjectLike([1, 2, 3]);
+// => true
+
+_.isObjectLike(_.noop);
+// => false
+
+_.isObjectLike(null);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isplainobjectvalue"></a>`_.isPlainObject(value)`
+<a href="#_isplainobjectvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11208 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isplainobject "See the npm package")
+
+Checks if `value` is a plain object, that is, an object created by the
+`Object` constructor or one with a `[[Prototype]]` of `null`.
+
+#### Since
+0.8.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a plain object, else `false`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isregexpvalue"></a>`_.isRegExp(value)`
+<a href="#_isregexpvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11240 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isregexp "See the npm package")
+
+Checks if `value` is classified as a `RegExp` object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isRegExp(/abc/);
+// => true
+
+_.isRegExp('/abc/');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_issafeintegervalue"></a>`_.isSafeInteger(value)`
+<a href="#_issafeintegervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11272 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.issafeinteger "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** This method is based on
+[`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger).
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is a safe integer, else `false`.
+
+#### Example
+```js
+_.isSafeInteger(3);
+// => true
+
+_.isSafeInteger(Number.MIN_VALUE);
+// => false
+
+_.isSafeInteger(Infinity);
+// => false
+
+_.isSafeInteger('3');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_issetvalue"></a>`_.isSet(value)`
+<a href="#_issetvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11294 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isset "See the npm package")
+
+Checks if `value` is classified as a `Set` object.
+
+#### Since
+4.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isSet(new Set);
+// => true
+
+_.isSet(new WeakSet);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isstringvalue"></a>`_.isString(value)`
+<a href="#_isstringvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11316 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isstring "See the npm package")
+
+Checks if `value` is classified as a `String` primitive or object.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isString('abc');
+// => true
+
+_.isString(1);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_issymbolvalue"></a>`_.isSymbol(value)`
+<a href="#_issymbolvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11339 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.issymbol "See the npm package")
+
+Checks if `value` is classified as a `Symbol` primitive or object.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isSymbol(Symbol.iterator);
+// => true
+
+_.isSymbol('abc');
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_istypedarrayvalue"></a>`_.isTypedArray(value)`
+<a href="#_istypedarrayvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11362 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.istypedarray "See the npm package")
+
+Checks if `value` is classified as a typed array.
+
+#### Since
+3.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isTypedArray(new Uint8Array);
+// => true
+
+_.isTypedArray([]);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isundefinedvalue"></a>`_.isUndefined(value)`
+<a href="#_isundefinedvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11384 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isundefined "See the npm package")
+
+Checks if `value` is `undefined`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is `undefined`, else `false`.
+
+#### Example
+```js
+_.isUndefined(void 0);
+// => true
+
+_.isUndefined(null);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isweakmapvalue"></a>`_.isWeakMap(value)`
+<a href="#_isweakmapvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11406 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isweakmap "See the npm package")
+
+Checks if `value` is classified as a `WeakMap` object.
+
+#### Since
+4.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isWeakMap(new WeakMap);
+// => true
+
+_.isWeakMap(new Map);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_isweaksetvalue"></a>`_.isWeakSet(value)`
+<a href="#_isweaksetvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11428 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.isweakset "See the npm package")
+
+Checks if `value` is classified as a `WeakSet` object.
+
+#### Since
+4.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is correctly classified, else `false`.
+
+#### Example
+```js
+_.isWeakSet(new WeakSet);
+// => true
+
+_.isWeakSet(new Set);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ltvalue-other"></a>`_.lt(value, other)`
+<a href="#_ltvalue-other">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11455 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.lt "See the npm package")
+
+Checks if `value` is less than `other`.
+
+#### Since
+3.9.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is less than `other`, else `false`.
+
+#### Example
+```js
+_.lt(1, 3);
+// => true
+
+_.lt(3, 3);
+// => false
+
+_.lt(3, 1);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ltevalue-other"></a>`_.lte(value, other)`
+<a href="#_ltevalue-other">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11480 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.lte "See the npm package")
+
+Checks if `value` is less than or equal to `other`.
+
+#### Since
+3.9.0
+#### Arguments
+1. `value` *(&#42;)*: The value to compare.
+2. `other` *(&#42;)*: The other value to compare.
+
+#### Returns
+*(boolean)*: Returns `true` if `value` is less than or equal to `other`, else `false`.
+
+#### Example
+```js
+_.lte(1, 3);
+// => true
+
+_.lte(3, 3);
+// => true
+
+_.lte(3, 1);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_toarrayvalue"></a>`_.toArray(value)`
+<a href="#_toarrayvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11507 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.toarray "See the npm package")
+
+Converts `value` to an array.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to convert.
+
+#### Returns
+*(Array)*: Returns the converted array.
+
+#### Example
+```js
+_.toArray({ 'a': 1, 'b': 2 });
+// => [1, 2]
+
+_.toArray('abc');
+// => ['a', 'b', 'c']
+
+_.toArray(1);
+// => []
+
+_.toArray(null);
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tointegervalue"></a>`_.toInteger(value)`
+<a href="#_tointegervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11549 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tointeger "See the npm package")
+
+Converts `value` to an integer.
+<br>
+<br>
+**Note:** This function is loosely based on
+[`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to convert.
+
+#### Returns
+*(number)*: Returns the converted integer.
+
+#### Example
+```js
+_.toInteger(3);
+// => 3
+
+_.toInteger(Number.MIN_VALUE);
+// => 0
+
+_.toInteger(Infinity);
+// => 1.7976931348623157e+308
+
+_.toInteger('3');
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tolengthvalue"></a>`_.toLength(value)`
+<a href="#_tolengthvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11589 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tolength "See the npm package")
+
+Converts `value` to an integer suitable for use as the length of an
+array-like object.
+<br>
+<br>
+**Note:** This method is based on
+[`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to convert.
+
+#### Returns
+*(number)*: Returns the converted integer.
+
+#### Example
+```js
+_.toLength(3);
+// => 3
+
+_.toLength(Number.MIN_VALUE);
+// => 0
+
+_.toLength(Infinity);
+// => 4294967295
+
+_.toLength('3');
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tonumbervalue"></a>`_.toNumber(value)`
+<a href="#_tonumbervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11616 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tonumber "See the npm package")
+
+Converts `value` to a number.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to process.
+
+#### Returns
+*(number)*: Returns the number.
+
+#### Example
+```js
+_.toNumber(3);
+// => 3
+
+_.toNumber(Number.MIN_VALUE);
+// => 5e-324
+
+_.toNumber(Infinity);
+// => Infinity
+
+_.toNumber('3');
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_toplainobjectvalue"></a>`_.toPlainObject(value)`
+<a href="#_toplainobjectvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11661 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.toplainobject "See the npm package")
+
+Converts `value` to a plain object flattening inherited enumerable string
+keyed properties of `value` to own properties of the plain object.
+
+#### Since
+3.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to convert.
+
+#### Returns
+*(Object)*: Returns the converted plain object.
+
+#### Example
+```js
+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 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tosafeintegervalue"></a>`_.toSafeInteger(value)`
+<a href="#_tosafeintegervalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11689 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tosafeinteger "See the npm package")
+
+Converts `value` to a safe integer. A safe integer can be compared and
+represented correctly.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to convert.
+
+#### Returns
+*(number)*: Returns the converted integer.
+
+#### Example
+```js
+_.toSafeInteger(3);
+// => 3
+
+_.toSafeInteger(Number.MIN_VALUE);
+// => 0
+
+_.toSafeInteger(Infinity);
+// => 9007199254740991
+
+_.toSafeInteger('3');
+// => 3
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tostringvalue"></a>`_.toString(value)`
+<a href="#_tostringvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11714 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tostring "See the npm package")
+
+Converts `value` to a string. An empty string is returned for `null`
+and `undefined` values. The sign of `-0` is preserved.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to process.
+
+#### Returns
+*(string)*: Returns the string.
+
+#### Example
+```js
+_.toString(null);
+// => ''
+
+_.toString(-0);
+// => '-0'
+
+_.toString([1, 2, 3]);
+// => '1,2,3'
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Math” Methods`
+
+<!-- div -->
+
+### <a id="_addaugend-addend"></a>`_.add(augend, addend)`
+<a href="#_addaugend-addend">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15229 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.add "See the npm package")
+
+Adds two numbers.
+
+#### Since
+3.4.0
+#### Arguments
+1. `augend` *(number)*: The first number in an addition.
+2. `addend` *(number)*: The second number in an addition.
+
+#### Returns
+*(number)*: Returns the total.
+
+#### Example
+```js
+_.add(6, 4);
+// => 10
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_ceilnumber-precision0"></a>`_.ceil(number, [precision=0])`
+<a href="#_ceilnumber-precision0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15254 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.ceil "See the npm package")
+
+Computes `number` rounded up to `precision`.
+
+#### Since
+3.10.0
+#### Arguments
+1. `number` *(number)*: The number to round up.
+2. `[precision=0]` *(number)*: The precision to round up to.
+
+#### Returns
+*(number)*: Returns the rounded up number.
+
+#### Example
+```js
+_.ceil(4.006);
+// => 5
+
+_.ceil(6.004, 2);
+// => 6.01
+
+_.ceil(6040, -2);
+// => 6100
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_dividedividend-divisor"></a>`_.divide(dividend, divisor)`
+<a href="#_dividedividend-divisor">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15271 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.divide "See the npm package")
+
+Divide two numbers.
+
+#### Since
+4.7.0
+#### Arguments
+1. `dividend` *(number)*: The first number in a division.
+2. `divisor` *(number)*: The second number in a division.
+
+#### Returns
+*(number)*: Returns the quotient.
+
+#### Example
+```js
+_.divide(6, 4);
+// => 1.5
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_floornumber-precision0"></a>`_.floor(number, [precision=0])`
+<a href="#_floornumber-precision0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15296 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.floor "See the npm package")
+
+Computes `number` rounded down to `precision`.
+
+#### Since
+3.10.0
+#### Arguments
+1. `number` *(number)*: The number to round down.
+2. `[precision=0]` *(number)*: The precision to round down to.
+
+#### Returns
+*(number)*: Returns the rounded down number.
+
+#### Example
+```js
+_.floor(4.006);
+// => 4
+
+_.floor(0.046, 2);
+// => 0.04
+
+_.floor(4060, -2);
+// => 4000
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_maxarray"></a>`_.max(array)`
+<a href="#_maxarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15316 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.max "See the npm package")
+
+Computes the maximum value of `array`. If `array` is empty or falsey,
+`undefined` is returned.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+
+#### Returns
+*(&#42;)*: Returns the maximum value.
+
+#### Example
+```js
+_.max([4, 2, 8, 6]);
+// => 8
+
+_.max([]);
+// => undefined
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_maxbyarray-iteratee_identity"></a>`_.maxBy(array, [iteratee=_.identity])`
+<a href="#_maxbyarray-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15346 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.maxby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(&#42;)*: Returns the maximum value.
+
+#### Example
+```js
+var objects = [{ 'n': 1 }, { 'n': 2 }];
+
+_.maxBy(objects, function(o) { return o.n; });
+// => { 'n': 2 }
+
+// The `_.property` iteratee shorthand.
+_.maxBy(objects, 'n');
+// => { 'n': 2 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_meanarray"></a>`_.mean(array)`
+<a href="#_meanarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15366 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.mean "See the npm package")
+
+Computes the mean of the values in `array`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+
+#### Returns
+*(number)*: Returns the mean.
+
+#### Example
+```js
+_.mean([4, 2, 8, 6]);
+// => 5
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_meanbyarray-iteratee_identity"></a>`_.meanBy(array, [iteratee=_.identity])`
+<a href="#_meanbyarray-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15394 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.meanby "See the npm package")
+
+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)*.
+
+#### Since
+4.7.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(number)*: Returns the mean.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_minarray"></a>`_.min(array)`
+<a href="#_minarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15416 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.min "See the npm package")
+
+Computes the minimum value of `array`. If `array` is empty or falsey,
+`undefined` is returned.
+
+#### Since
+0.1.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+
+#### Returns
+*(&#42;)*: Returns the minimum value.
+
+#### Example
+```js
+_.min([4, 2, 8, 6]);
+// => 2
+
+_.min([]);
+// => undefined
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_minbyarray-iteratee_identity"></a>`_.minBy(array, [iteratee=_.identity])`
+<a href="#_minbyarray-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15446 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.minby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(&#42;)*: Returns the minimum value.
+
+#### Example
+```js
+var objects = [{ 'n': 1 }, { 'n': 2 }];
+
+_.minBy(objects, function(o) { return o.n; });
+// => { 'n': 1 }
+
+// The `_.property` iteratee shorthand.
+_.minBy(objects, 'n');
+// => { 'n': 1 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_multiplymultiplier-multiplicand"></a>`_.multiply(multiplier, multiplicand)`
+<a href="#_multiplymultiplier-multiplicand">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15467 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.multiply "See the npm package")
+
+Multiply two numbers.
+
+#### Since
+4.7.0
+#### Arguments
+1. `multiplier` *(number)*: The first number in a multiplication.
+2. `multiplicand` *(number)*: The second number in a multiplication.
+
+#### Returns
+*(number)*: Returns the product.
+
+#### Example
+```js
+_.multiply(6, 4);
+// => 24
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_roundnumber-precision0"></a>`_.round(number, [precision=0])`
+<a href="#_roundnumber-precision0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15492 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.round "See the npm package")
+
+Computes `number` rounded to `precision`.
+
+#### Since
+3.10.0
+#### Arguments
+1. `number` *(number)*: The number to round.
+2. `[precision=0]` *(number)*: The precision to round to.
+
+#### Returns
+*(number)*: Returns the rounded number.
+
+#### Example
+```js
+_.round(4.006);
+// => 4
+
+_.round(4.006, 2);
+// => 4.01
+
+_.round(4060, -2);
+// => 4100
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_subtractminuend-subtrahend"></a>`_.subtract(minuend, subtrahend)`
+<a href="#_subtractminuend-subtrahend">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15509 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.subtract "See the npm package")
+
+Subtract two numbers.
+
+#### Since
+4.0.0
+#### Arguments
+1. `minuend` *(number)*: The first number in a subtraction.
+2. `subtrahend` *(number)*: The second number in a subtraction.
+
+#### Returns
+*(number)*: Returns the difference.
+
+#### Example
+```js
+_.subtract(6, 4);
+// => 2
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sumarray"></a>`_.sum(array)`
+<a href="#_sumarray">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15527 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sum "See the npm package")
+
+Computes the sum of the values in `array`.
+
+#### Since
+3.4.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+
+#### Returns
+*(number)*: Returns the sum.
+
+#### Example
+```js
+_.sum([4, 2, 8, 6]);
+// => 20
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_sumbyarray-iteratee_identity"></a>`_.sumBy(array, [iteratee=_.identity])`
+<a href="#_sumbyarray-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15557 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.sumby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `array` *(Array)*: The array to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(number)*: Returns the sum.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Number” Methods`
+
+<!-- div -->
+
+### <a id="_clampnumber-lower-upper"></a>`_.clamp(number, [lower], upper)`
+<a href="#_clampnumber-lower-upper">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13139 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.clamp "See the npm package")
+
+Clamps `number` within the inclusive `lower` and `upper` bounds.
+
+#### Since
+4.0.0
+#### Arguments
+1. `number` *(number)*: The number to clamp.
+2. `[lower]` *(number)*: The lower bound.
+3. `upper` *(number)*: The upper bound.
+
+#### Returns
+*(number)*: Returns the clamped number.
+
+#### Example
+```js
+_.clamp(-10, -5, 5);
+// => -5
+
+_.clamp(10, -5, 5);
+// => 5
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_inrangenumber-start0-end"></a>`_.inRange(number, [start=0], end)`
+<a href="#_inrangenumber-start0-end">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13193 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.inrange "See the npm package")
+
+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.
+
+#### Since
+3.3.0
+#### Arguments
+1. `number` *(number)*: The number to check.
+2. `[start=0]` *(number)*: The start of the range.
+3. `end` *(number)*: The end of the range.
+
+#### Returns
+*(boolean)*: Returns `true` if `number` is in the range, else `false`.
+
+#### Example
+```js
+_.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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_randomlower0-upper1-floating"></a>`_.random([lower=0], [upper=1], [floating])`
+<a href="#_randomlower0-upper1-floating">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13236 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.random "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** JavaScript follows the IEEE-754 standard for resolving
+floating-point values which can produce unexpected results.
+
+#### Since
+0.7.0
+#### Arguments
+1. `[lower=0]` *(number)*: The lower bound.
+2. `[upper=1]` *(number)*: The upper bound.
+3. `[floating]` *(boolean)*: Specify returning a floating-point number.
+
+#### Returns
+*(number)*: Returns the random number.
+
+#### Example
+```js
+_.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
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Object” Methods`
+
+<!-- div -->
+
+### <a id="_assignobject-sources"></a>`_.assign(object, [sources])`
+<a href="#_assignobject-sources">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11752 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.assign "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** This method mutates `object` and is loosely based on
+[`Object.assign`](https://mdn.io/Object/assign).
+
+#### Since
+0.10.0
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `[sources]` *(...Object)*: The source objects.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+function Foo() {
+  this.c = 3;
+}
+
+function Bar() {
+  this.e = 5;
+}
+
+Foo.prototype.d = 4;
+Bar.prototype.f = 6;
+
+_.assign({ 'a': 1 }, new Foo, new Bar);
+// => { 'a': 1, 'c': 3, 'e': 5 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_assigninobject-sources"></a>`_.assignIn(object, [sources])`
+<a href="#_assigninobject-sources">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11795 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.assignin "See the npm package")
+
+This method is like `_.assign` except that it iterates over own and
+inherited source properties.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.0.0
+#### Aliases
+*_.extend*
+
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `[sources]` *(...Object)*: The source objects.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+function Foo() {
+  this.b = 2;
+}
+
+function Bar() {
+  this.d = 4;
+}
+
+Foo.prototype.c = 3;
+Bar.prototype.e = 5;
+
+_.assignIn({ 'a': 1 }, new Foo, new Bar);
+// => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_assigninwithobject-sources-customizer"></a>`_.assignInWith(object, sources, [customizer])`
+<a href="#_assigninwithobject-sources-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11834 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.assigninwith "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.0.0
+#### Aliases
+*_.extendWith*
+
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `sources` *(...Object)*: The source objects.
+3. `[customizer]` *(Function)*: The function to customize assigned values.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_assignwithobject-sources-customizer"></a>`_.assignWith(object, sources, [customizer])`
+<a href="#_assignwithobject-sources-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11866 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.assignwith "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `sources` *(...Object)*: The source objects.
+3. `[customizer]` *(Function)*: The function to customize assigned values.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_atobject-paths"></a>`_.at(object, [paths])`
+<a href="#_atobject-paths">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11890 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.at "See the npm package")
+
+Creates an array of values corresponding to `paths` of `object`.
+
+#### Since
+1.0.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[paths]` *(...(string|string&#91;&#93;))*: The property paths of elements to pick.
+
+#### Returns
+*(Array)*: Returns the new array of picked elements.
+
+#### Example
+```js
+var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+
+_.at(object, ['a[0].b.c', 'a[1]']);
+// => [3, 4]
+
+_.at(['a', 'b', 'c'], 0, 2);
+// => ['a', 'c']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_createprototype-properties"></a>`_.create(prototype, [properties])`
+<a href="#_createprototype-properties">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11928 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.create "See the npm package")
+
+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.
+
+#### Since
+2.3.0
+#### Arguments
+1. `prototype` *(Object)*: The object to inherit from.
+2. `[properties]` *(Object)*: The properties to assign to the object.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_defaultsobject-sources"></a>`_.defaults(object, [sources])`
+<a href="#_defaultsobject-sources">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11954 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.defaults "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `[sources]` *(...Object)*: The source objects.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+_.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+// => { 'user': 'barney', 'age': 36 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_defaultsdeepobject-sources"></a>`_.defaultsDeep(object, [sources])`
+<a href="#_defaultsdeepobject-sources">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L11979 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.defaultsdeep "See the npm package")
+
+This method is like `_.defaults` except that it recursively assigns
+default properties.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+3.10.0
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `[sources]` *(...Object)*: The source objects.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
+// => { 'user': { 'name': 'barney', 'age': 36 } }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_findkeyobject-predicate_identity"></a>`_.findKey(object, [predicate=_.identity])`
+<a href="#_findkeyobject-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12020 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.findkey "See the npm package")
+
+This method is like `_.find` except that it returns the key of the first
+element `predicate` returns truthy for instead of the element itself.
+
+#### Since
+1.1.0
+#### Arguments
+1. `object` *(Object)*: The object to search.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(&#42;)*: Returns the key of the matched element, else `undefined`.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_findlastkeyobject-predicate_identity"></a>`_.findLastKey(object, [predicate=_.identity])`
+<a href="#_findlastkeyobject-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12060 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.findlastkey "See the npm package")
+
+This method is like `_.findKey` except that it iterates over elements of
+a collection in the opposite order.
+
+#### Since
+2.0.0
+#### Arguments
+1. `object` *(Object)*: The object to search.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(&#42;)*: Returns the key of the matched element, else `undefined`.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_forinobject-iteratee_identity"></a>`_.forIn(object, [iteratee=_.identity])`
+<a href="#_forinobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12092 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.forin "See the npm package")
+
+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`.
+
+#### Since
+0.3.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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).
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_forinrightobject-iteratee_identity"></a>`_.forInRight(object, [iteratee=_.identity])`
+<a href="#_forinrightobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12124 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.forinright "See the npm package")
+
+This method is like `_.forIn` except that it iterates over properties of
+`object` in the opposite order.
+
+#### Since
+2.0.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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'.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_forownobject-iteratee_identity"></a>`_.forOwn(object, [iteratee=_.identity])`
+<a href="#_forownobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12158 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.forown "See the npm package")
+
+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`.
+
+#### Since
+0.3.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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).
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_forownrightobject-iteratee_identity"></a>`_.forOwnRight(object, [iteratee=_.identity])`
+<a href="#_forownrightobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12188 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.forownright "See the npm package")
+
+This method is like `_.forOwn` except that it iterates over properties of
+`object` in the opposite order.
+
+#### Since
+2.0.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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'.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_functionsobject"></a>`_.functions(object)`
+<a href="#_functionsobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12215 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.functions "See the npm package")
+
+Creates an array of function property names from own enumerable properties
+of `object`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The object to inspect.
+
+#### Returns
+*(Array)*: Returns the new array of property names.
+
+#### Example
+```js
+function Foo() {
+  this.a = _.constant('a');
+  this.b = _.constant('b');
+}
+
+Foo.prototype.c = _.constant('c');
+
+_.functions(new Foo);
+// => ['a', 'b']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_functionsinobject"></a>`_.functionsIn(object)`
+<a href="#_functionsinobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12242 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.functionsin "See the npm package")
+
+Creates an array of function property names from own and inherited
+enumerable properties of `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The object to inspect.
+
+#### Returns
+*(Array)*: Returns the new array of property names.
+
+#### Example
+```js
+function Foo() {
+  this.a = _.constant('a');
+  this.b = _.constant('b');
+}
+
+Foo.prototype.c = _.constant('c');
+
+_.functionsIn(new Foo);
+// => ['a', 'b', 'c']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_getobject-path-defaultvalue"></a>`_.get(object, path, [defaultValue])`
+<a href="#_getobject-path-defaultvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12271 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.get "See the npm package")
+
+Gets the value at `path` of `object`. If the resolved value is
+`undefined`, the `defaultValue` is used in its place.
+
+#### Since
+3.7.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+2. `path` *(Array|string)*: The path of the property to get.
+3. `[defaultValue]` *(&#42;)*: The value returned for `undefined` resolved values.
+
+#### Returns
+*(&#42;)*: Returns the resolved value.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_hasobject-path"></a>`_.has(object, path)`
+<a href="#_hasobject-path">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12303 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.has "See the npm package")
+
+Checks if `path` is a direct property of `object`.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+2. `path` *(Array|string)*: The path to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `path` exists, else `false`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_hasinobject-path"></a>`_.hasIn(object, path)`
+<a href="#_hasinobject-path">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12333 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.hasin "See the npm package")
+
+Checks if `path` is a direct or inherited property of `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+2. `path` *(Array|string)*: The path to check.
+
+#### Returns
+*(boolean)*: Returns `true` if `path` exists, else `false`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_invertobject"></a>`_.invert(object)`
+<a href="#_invertobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12355 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.invert "See the npm package")
+
+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.
+
+#### Since
+0.7.0
+#### Arguments
+1. `object` *(Object)*: The object to invert.
+
+#### Returns
+*(Object)*: Returns the new inverted object.
+
+#### Example
+```js
+var object = { 'a': 1, 'b': 2, 'c': 1 };
+
+_.invert(object);
+// => { '1': 'c', '2': 'b' }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_invertbyobject-iteratee_identity"></a>`_.invertBy(object, [iteratee=_.identity])`
+<a href="#_invertbyobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12386 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.invertby "See the npm package")
+
+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)*.
+
+#### Since
+4.1.0
+#### Arguments
+1. `object` *(Object)*: The object to invert.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The iteratee invoked per element.
+
+#### Returns
+*(Object)*: Returns the new inverted object.
+
+#### Example
+```js
+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'] }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_invokeobject-path-args"></a>`_.invoke(object, path, [args])`
+<a href="#_invokeobject-path-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12412 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.invoke "See the npm package")
+
+Invokes the method at `path` of `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+2. `path` *(Array|string)*: The path of the method to invoke.
+3. `[args]` *(...&#42;)*: The arguments to invoke the method with.
+
+#### Returns
+*(&#42;)*: Returns the result of the invoked method.
+
+#### Example
+```js
+var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
+
+_.invoke(object, 'a[0].b.c.slice', 1, 3);
+// => [2, 3]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_keysobject"></a>`_.keys(object)`
+<a href="#_keysobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12442 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.keys "See the npm package")
+
+Creates an array of the own enumerable property names of `object`.
+<br>
+<br>
+**Note:** Non-object values are coerced to objects. See the
+[ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+for more details.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the array of property names.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_keysinobject"></a>`_.keysIn(object)`
+<a href="#_keysinobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12485 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.keysin "See the npm package")
+
+Creates an array of the own and inherited enumerable property names of `object`.
+<br>
+<br>
+**Note:** Non-object values are coerced to objects.
+
+#### Since
+3.0.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the array of property names.
+
+#### Example
+```js
+function Foo() {
+  this.a = 1;
+  this.b = 2;
+}
+
+Foo.prototype.c = 3;
+
+_.keysIn(new Foo);
+// => ['a', 'b', 'c'] (iteration order is not guaranteed)
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_mapkeysobject-iteratee_identity"></a>`_.mapKeys(object, [iteratee=_.identity])`
+<a href="#_mapkeysobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12527 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.mapkeys "See the npm package")
+
+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)*.
+
+#### Since
+3.8.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Object)*: Returns the new mapped object.
+
+#### Example
+```js
+_.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
+  return key + value;
+});
+// => { 'a1': 1, 'b2': 2 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_mapvaluesobject-iteratee_identity"></a>`_.mapValues(object, [iteratee=_.identity])`
+<a href="#_mapvaluesobject-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12566 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.mapvalues "See the npm package")
+
+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:<br>
+*(value, key, object)*.
+
+#### Since
+2.4.0
+#### Arguments
+1. `object` *(Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Array|Function|Object|string)*: The function invoked per iteration.
+
+#### Returns
+*(Object)*: Returns the new mapped object.
+
+#### Example
+```js
+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)
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_mergeobject-sources"></a>`_.merge(object, [sources])`
+<a href="#_mergeobject-sources">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12607 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.merge "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+0.5.0
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `[sources]` *(...Object)*: The source objects.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+var users = {
+  'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
+};
+
+var ages = {
+  'data': [{ 'age': 36 }, { 'age': 40 }]
+};
+
+_.merge(users, ages);
+// => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_mergewithobject-sources-customizer"></a>`_.mergeWith(object, sources, customizer)`
+<a href="#_mergewithobject-sources-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12649 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.mergewith "See the npm package")
+
+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 seven arguments:<br>
+*(objValue, srcValue, key, object, source, stack)*.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The destination object.
+2. `sources` *(...Object)*: The source objects.
+3. `customizer` *(Function)*: The function to customize assigned values.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+function customizer(objValue, srcValue) {
+  if (_.isArray(objValue)) {
+    return objValue.concat(srcValue);
+  }
+}
+
+var object = {
+  'fruits': ['apple'],
+  'vegetables': ['beet']
+};
+
+var other = {
+  'fruits': ['banana'],
+  'vegetables': ['carrot']
+};
+
+_.mergeWith(object, other, customizer);
+// => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_omitobject-props"></a>`_.omit(object, [props])`
+<a href="#_omitobject-props">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12672 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.omit "See the npm package")
+
+The opposite of `_.pick`; this method creates an object composed of the
+own and inherited enumerable string keyed properties of `object` that are
+not omitted.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The source object.
+2. `[props]` *(...(string|string&#91;&#93;))*: The property identifiers to omit.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+var object = { 'a': 1, 'b': '2', 'c': 3 };
+
+_.omit(object, ['a', 'c']);
+// => { 'b': '2' }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_omitbyobject-predicate_identity"></a>`_.omitBy(object, [predicate=_.identity])`
+<a href="#_omitbyobject-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12701 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.omitby "See the npm package")
+
+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)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The source object.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per property.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+var object = { 'a': 1, 'b': '2', 'c': 3 };
+
+_.omitBy(object, _.isNumber);
+// => { 'b': '2' }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pickobject-props"></a>`_.pick(object, [props])`
+<a href="#_pickobject-props">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12725 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pick "See the npm package")
+
+Creates an object composed of the picked `object` properties.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The source object.
+2. `[props]` *(...(string|string&#91;&#93;))*: The property identifiers to pick.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+var object = { 'a': 1, 'b': '2', 'c': 3 };
+
+_.pick(object, ['a', 'c']);
+// => { 'a': 1, 'c': 3 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_pickbyobject-predicate_identity"></a>`_.pickBy(object, [predicate=_.identity])`
+<a href="#_pickbyobject-predicate_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12748 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pickby "See the npm package")
+
+Creates an object composed of the `object` properties `predicate` returns
+truthy for. The predicate is invoked with two arguments: *(value, key)*.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The source object.
+2. `[predicate=_.identity]` *(Array|Function|Object|string)*: The function invoked per property.
+
+#### Returns
+*(Object)*: Returns the new object.
+
+#### Example
+```js
+var object = { 'a': 1, 'b': '2', 'c': 3 };
+
+_.pickBy(object, _.isNumber);
+// => { 'a': 1, 'c': 3 }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_resultobject-path-defaultvalue"></a>`_.result(object, path, [defaultValue])`
+<a href="#_resultobject-path-defaultvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12781 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.result "See the npm package")
+
+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.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+2. `path` *(Array|string)*: The path of the property to resolve.
+3. `[defaultValue]` *(&#42;)*: The value returned for `undefined` resolved values.
+
+#### Returns
+*(&#42;)*: Returns the resolved value.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_setobject-path-value"></a>`_.set(object, path, value)`
+<a href="#_setobject-path-value">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12831 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.set "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+3.7.0
+#### Arguments
+1. `object` *(Object)*: The object to modify.
+2. `path` *(Array|string)*: The path of the property to set.
+3. `value` *(&#42;)*: The value to set.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_setwithobject-path-value-customizer"></a>`_.setWith(object, path, value, [customizer])`
+<a href="#_setwithobject-path-value-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12859 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.setwith "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The object to modify.
+2. `path` *(Array|string)*: The path of the property to set.
+3. `value` *(&#42;)*: The value to set.
+4. `[customizer]` *(Function)*: The function to customize assigned values.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+var object = {};
+
+_.setWith(object, '[0][1]', 'a', Object);
+// => { '0': { '1': 'a' } }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_topairsobject"></a>`_.toPairs(object)`
+<a href="#_topairsobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12887 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.topairs "See the npm package")
+
+Creates an array of own enumerable string keyed-value pairs for `object`
+which can be consumed by `_.fromPairs`.
+
+#### Since
+4.0.0
+#### Aliases
+*_.entries*
+
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the new array of key-value pairs.
+
+#### Example
+```js
+function Foo() {
+  this.a = 1;
+  this.b = 2;
+}
+
+Foo.prototype.c = 3;
+
+_.toPairs(new Foo);
+// => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_topairsinobject"></a>`_.toPairsIn(object)`
+<a href="#_topairsinobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12914 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.topairsin "See the npm package")
+
+Creates an array of own and inherited enumerable string keyed-value pairs
+for `object` which can be consumed by `_.fromPairs`.
+
+#### Since
+4.0.0
+#### Aliases
+*_.entriesIn*
+
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the new array of key-value pairs.
+
+#### Example
+```js
+function Foo() {
+  this.a = 1;
+  this.b = 2;
+}
+
+Foo.prototype.c = 3;
+
+_.toPairsIn(new Foo);
+// => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_transformobject-iteratee_identity-accumulator"></a>`_.transform(object, [iteratee=_.identity], [accumulator])`
+<a href="#_transformobject-iteratee_identity-accumulator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12947 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.transform "See the npm package")
+
+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. The iteratee is invoked
+with four arguments: *(accumulator, value, key, object)*. Iteratee functions
+may exit iteration early by explicitly returning `false`.
+
+#### Since
+1.3.0
+#### Arguments
+1. `object` *(Array|Object)*: The object to iterate over.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+3. `[accumulator]` *(&#42;)*: The custom accumulator value.
+
+#### Returns
+*(&#42;)*: Returns the accumulated value.
+
+#### Example
+```js
+_.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'] }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unsetobject-path"></a>`_.unset(object, path)`
+<a href="#_unsetobject-path">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L12996 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unset "See the npm package")
+
+Removes the property at `path` of `object`.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `object` *(Object)*: The object to modify.
+2. `path` *(Array|string)*: The path of the property to unset.
+
+#### Returns
+*(boolean)*: Returns `true` if the property is deleted, else `false`.
+
+#### Example
+```js
+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': {} }] };
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_updateobject-path-updater"></a>`_.update(object, path, updater)`
+<a href="#_updateobject-path-updater">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13027 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.update "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.6.0
+#### Arguments
+1. `object` *(Object)*: The object to modify.
+2. `path` *(Array|string)*: The path of the property to set.
+3. `updater` *(Function)*: The function to produce the updated value.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_updatewithobject-path-updater-customizer"></a>`_.updateWith(object, path, updater, [customizer])`
+<a href="#_updatewithobject-path-updater-customizer">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13055 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.updatewith "See the npm package")
+
+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)*.
+<br>
+<br>
+**Note:** This method mutates `object`.
+
+#### Since
+4.6.0
+#### Arguments
+1. `object` *(Object)*: The object to modify.
+2. `path` *(Array|string)*: The path of the property to set.
+3. `updater` *(Function)*: The function to produce the updated value.
+4. `[customizer]` *(Function)*: The function to customize assigned values.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+var object = {};
+
+_.updateWith(object, '[0][1]', _.constant('a'), Object);
+// => { '0': { '1': 'a' } }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_valuesobject"></a>`_.values(object)`
+<a href="#_valuesobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13086 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.values "See the npm package")
+
+Creates an array of the own enumerable string keyed property values of `object`.
+<br>
+<br>
+**Note:** Non-object values are coerced to objects.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the array of property values.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_valuesinobject"></a>`_.valuesIn(object)`
+<a href="#_valuesinobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13114 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.valuesin "See the npm package")
+
+Creates an array of the own and inherited enumerable string keyed property
+values of `object`.
+<br>
+<br>
+**Note:** Non-object values are coerced to objects.
+
+#### Since
+3.0.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Array)*: Returns the array of property values.
+
+#### Example
+```js
+function Foo() {
+  this.a = 1;
+  this.b = 2;
+}
+
+Foo.prototype.c = 3;
+
+_.valuesIn(new Foo);
+// => [1, 2, 3] (iteration order is not guaranteed)
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Seq” Methods`
+
+<!-- div -->
+
+### <a id="_value"></a>`_(value)`
+<a href="#_value">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1457 "View in source") [&#x24C9;][1]
+
+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`.
+<br>
+<br>
+Explicit chain sequences, which must be unwrapped with `_#value`, may be
+enabled using `_.chain`.
+<br>
+<br>
+The execution of chained methods is lazy, that is, it's deferred until
+`_#value` is implicitly or explicitly called.
+<br>
+<br>
+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 of at least `200` elements
+and any iteratees accept only one argument. The heuristic for whether a
+section qualifies for shortcut fusion is subject to change.
+<br>
+<br>
+Chaining is supported in custom builds as long as the `_#value` method is
+directly or indirectly included in the build.
+<br>
+<br>
+In addition to lodash methods, wrappers have `Array` and `String` methods.
+<br>
+<br>
+The wrapper `Array` methods are:<br>
+`concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
+<br>
+<br>
+The wrapper `String` methods are:<br>
+`replace` and `split`
+<br>
+<br>
+The wrapper methods that support shortcut fusion are:<br>
+`at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
+`findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
+`tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
+<br>
+<br>
+The chainable wrapper methods are:<br>
+`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`
+<br>
+<br>
+The wrapper methods that are **not** chainable by default are:<br>
+`add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
+`cloneDeep`, `cloneDeepWith`, `cloneWith`, `deburr`, `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`, `subtract`, `sum`, `sumBy`, `template`, `times`, `toInteger`,
+`toJSON`, `toLength`, `toLower`, `toNumber`, `toSafeInteger`, `toString`,
+`toUpper`, `trim`, `trimEnd`, `trimStart`, `truncate`, `unescape`,
+`uniqueId`, `upperCase`, `upperFirst`, `value`, and `words`
+
+#### Arguments
+1. `value` *(&#42;)*: The value to wrap in a `lodash` instance.
+
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+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
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_chainvalue"></a>`_.chain(value)`
+<a href="#_chainvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7876 "View in source") [&#x24C9;][1]
+
+Creates a `lodash` wrapper instance that wraps `value` with explicit method
+chain sequences enabled. The result of such sequences must be unwrapped
+with `_#value`.
+
+#### Since
+1.3.0
+#### Arguments
+1. `value` *(&#42;)*: The value to wrap.
+
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+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'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tapvalue-interceptor"></a>`_.tap(value, interceptor)`
+<a href="#_tapvalue-interceptor">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7905 "View in source") [&#x24C9;][1]
+
+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.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: The value to provide to `interceptor`.
+2. `interceptor` *(Function)*: The function to invoke.
+
+#### Returns
+*(&#42;)*: Returns `value`.
+
+#### Example
+```js
+_([1, 2, 3])
+ .tap(function(array) {
+   // Mutate input array.
+   array.pop();
+ })
+ .reverse()
+ .value();
+// => [2, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_thruvalue-interceptor"></a>`_.thru(value, interceptor)`
+<a href="#_thruvalue-interceptor">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7933 "View in source") [&#x24C9;][1]
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to provide to `interceptor`.
+2. `interceptor` *(Function)*: The function to invoke.
+
+#### Returns
+*(&#42;)*: Returns the result of `interceptor`.
+
+#### Example
+```js
+_('  abc  ')
+ .chain()
+ .trim()
+ .thru(function(value) {
+   return [value];
+ })
+ .value();
+// => ['abc']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypesymboliterator"></a>`_.prototype[Symbol.iterator]()`
+<a href="#_prototypesymboliterator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8092 "View in source") [&#x24C9;][1]
+
+Enables the wrapper to be iterable.
+
+#### Since
+4.0.0
+#### Returns
+*(Object)*: Returns the wrapper object.
+
+#### Example
+```js
+var wrapped = _([1, 2]);
+
+wrapped[Symbol.iterator]() === wrapped;
+// => true
+
+Array.from(wrapped);
+// => [1, 2]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypeatpaths"></a>`_.prototype.at([paths])`
+<a href="#_prototypeatpaths">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L7956 "View in source") [&#x24C9;][1]
+
+This method is the wrapper version of `_.at`.
+
+#### Since
+1.0.0
+#### Arguments
+1. `[paths]` *(...(string|string&#91;&#93;))*: The property paths of elements to pick.
+
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+
+_(object).at(['a[0].b.c', 'a[1]']).value();
+// => [3, 4]
+
+_(['a', 'b', 'c']).at(0, 2).value();
+// => ['a', 'c']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypechain"></a>`_.prototype.chain()`
+<a href="#_prototypechain">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8008 "View in source") [&#x24C9;][1]
+
+Creates a `lodash` wrapper instance with explicit method chain sequences enabled.
+
+#### Since
+0.1.0
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+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' }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypecommit"></a>`_.prototype.commit()`
+<a href="#_prototypecommit">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8038 "View in source") [&#x24C9;][1]
+
+Executes the chain sequence and returns the wrapped result.
+
+#### Since
+3.2.0
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypenext"></a>`_.prototype.next()`
+<a href="#_prototypenext">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8064 "View in source") [&#x24C9;][1]
+
+Gets the next value on a wrapped object following the
+[iterator protocol](https://mdn.io/iteration_protocols#iterator).
+
+#### Since
+4.0.0
+#### Returns
+*(Object)*: Returns the next iterator value.
+
+#### Example
+```js
+var wrapped = _([1, 2]);
+
+wrapped.next();
+// => { 'done': false, 'value': 1 }
+
+wrapped.next();
+// => { 'done': false, 'value': 2 }
+
+wrapped.next();
+// => { 'done': true, 'value': undefined }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypeplantvalue"></a>`_.prototype.plant(value)`
+<a href="#_prototypeplantvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8120 "View in source") [&#x24C9;][1]
+
+Creates a clone of the chain sequence planting `value` as the wrapped value.
+
+#### Since
+3.2.0
+#### Arguments
+1. `value` *(&#42;)*: The value to plant.
+
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypereverse"></a>`_.prototype.reverse()`
+<a href="#_prototypereverse">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8160 "View in source") [&#x24C9;][1]
+
+This method is the wrapper version of `_.reverse`.
+<br>
+<br>
+**Note:** This method mutates the wrapped array.
+
+#### Since
+0.1.0
+#### Returns
+*(Object)*: Returns the new `lodash` wrapper instance.
+
+#### Example
+```js
+var array = [1, 2, 3];
+
+_(array).reverse().value()
+// => [3, 2, 1]
+
+console.log(array);
+// => [3, 2, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_prototypevalue"></a>`_.prototype.value()`
+<a href="#_prototypevalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L8192 "View in source") [&#x24C9;][1]
+
+Executes the chain sequence to resolve the unwrapped value.
+
+#### Since
+0.1.0
+#### Aliases
+*_.prototype.toJSON, _.prototype.valueOf*
+
+#### Returns
+*(&#42;)*: Returns the resolved unwrapped value.
+
+#### Example
+```js
+_([1, 2, 3]).value();
+// => [1, 2, 3]
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“String” Methods`
+
+<!-- div -->
+
+### <a id="_camelcasestring"></a>`_.camelCase([string=''])`
+<a href="#_camelcasestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13297 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.camelcase "See the npm package")
+
+Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase).
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the camel cased string.
+
+#### Example
+```js
+_.camelCase('Foo Bar');
+// => 'fooBar'
+
+_.camelCase('--foo-bar--');
+// => 'fooBar'
+
+_.camelCase('__FOO_BAR__');
+// => 'fooBar'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_capitalizestring"></a>`_.capitalize([string=''])`
+<a href="#_capitalizestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13317 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.capitalize "See the npm package")
+
+Converts the first character of `string` to upper case and the remaining
+to lower case.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to capitalize.
+
+#### Returns
+*(string)*: Returns the capitalized string.
+
+#### Example
+```js
+_.capitalize('FRED');
+// => 'Fred'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_deburrstring"></a>`_.deburr([string=''])`
+<a href="#_deburrstring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13338 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.deburr "See the npm package")
+
+Deburrs `string` by converting
+[latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+to basic latin letters and removing
+[combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to deburr.
+
+#### Returns
+*(string)*: Returns the deburred string.
+
+#### Example
+```js
+_.deburr('déjà vu');
+// => 'deja vu'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_endswithstring-target-positionstringlength"></a>`_.endsWith([string=''], [target], [position=string.length])`
+<a href="#_endswithstring-target-positionstringlength">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13366 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.endswith "See the npm package")
+
+Checks if `string` ends with the given target string.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to search.
+2. `[target]` *(string)*: The string to search for.
+3. `[position=string.length]` *(number)*: The position to search from.
+
+#### Returns
+*(boolean)*: Returns `true` if `string` ends with `target`, else `false`.
+
+#### Example
+```js
+_.endsWith('abc', 'c');
+// => true
+
+_.endsWith('abc', 'b');
+// => false
+
+_.endsWith('abc', 'b', 2);
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_escapestring"></a>`_.escape([string=''])`
+<a href="#_escapestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13413 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.escape "See the npm package")
+
+Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
+their corresponding HTML entities.
+<br>
+<br>
+**Note:** No other characters are escaped. To escape additional
+characters use a third-party library like [_he_](https://mths.be/he).
+<br>
+<br>
+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.
+<br>
+<br>
+Backticks are escaped because in IE < `9`, they can break out of
+attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+[#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
+[#133](https://html5sec.org/#133) of the
+[HTML5 Security Cheatsheet](https://html5sec.org/) for more details.
+<br>
+<br>
+When working with HTML you should always
+[quote attribute values](http://wonko.com/post/html-escaping) to reduce
+XSS vectors.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[string='']` *(string)*: The string to escape.
+
+#### Returns
+*(string)*: Returns the escaped string.
+
+#### Example
+```js
+_.escape('fred, barney, & pebbles');
+// => 'fred, barney, &amp; pebbles'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_escaperegexpstring"></a>`_.escapeRegExp([string=''])`
+<a href="#_escaperegexpstring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13435 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package")
+
+Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+",
+"?", "(", ")", "[", "]", "{", "}", and "|" in `string`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to escape.
+
+#### Returns
+*(string)*: Returns the escaped string.
+
+#### Example
+```js
+_.escapeRegExp('[lodash](https://lodash.com/)');
+// => '\[lodash\]\(https://lodash\.com/\)'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_kebabcasestring"></a>`_.kebabCase([string=''])`
+<a href="#_kebabcasestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13463 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.kebabcase "See the npm package")
+
+Converts `string` to
+[kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the kebab cased string.
+
+#### Example
+```js
+_.kebabCase('Foo Bar');
+// => 'foo-bar'
+
+_.kebabCase('fooBar');
+// => 'foo-bar'
+
+_.kebabCase('__FOO_BAR__');
+// => 'foo-bar'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_lowercasestring"></a>`_.lowerCase([string=''])`
+<a href="#_lowercasestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13487 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.lowercase "See the npm package")
+
+Converts `string`, as space separated words, to lower case.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the lower cased string.
+
+#### Example
+```js
+_.lowerCase('--Foo-Bar--');
+// => 'foo bar'
+
+_.lowerCase('fooBar');
+// => 'foo bar'
+
+_.lowerCase('__FOO_BAR__');
+// => 'foo bar'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_lowerfirststring"></a>`_.lowerFirst([string=''])`
+<a href="#_lowerfirststring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13508 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.lowerfirst "See the npm package")
+
+Converts the first character of `string` to lower case.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the converted string.
+
+#### Example
+```js
+_.lowerFirst('Fred');
+// => 'fred'
+
+_.lowerFirst('FRED');
+// => 'fRED'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_padstring-length0-chars"></a>`_.pad([string=''], [length=0], [chars=' '])`
+<a href="#_padstring-length0-chars">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13533 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.pad "See the npm package")
+
+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`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to pad.
+2. `[length=0]` *(number)*: The padding length.
+3. `[chars=' ']` *(string)*: The string used as padding.
+
+#### Returns
+*(string)*: Returns the padded string.
+
+#### Example
+```js
+_.pad('abc', 8);
+// => '  abc   '
+
+_.pad('abc', 8, '_-');
+// => '_-abc_-_'
+
+_.pad('abc', 3);
+// => 'abc'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_padendstring-length0-chars"></a>`_.padEnd([string=''], [length=0], [chars=' '])`
+<a href="#_padendstring-length0-chars">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13572 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.padend "See the npm package")
+
+Pads `string` on the right side if it's shorter than `length`. Padding
+characters are truncated if they exceed `length`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to pad.
+2. `[length=0]` *(number)*: The padding length.
+3. `[chars=' ']` *(string)*: The string used as padding.
+
+#### Returns
+*(string)*: Returns the padded string.
+
+#### Example
+```js
+_.padEnd('abc', 6);
+// => 'abc   '
+
+_.padEnd('abc', 6, '_-');
+// => 'abc_-_'
+
+_.padEnd('abc', 3);
+// => 'abc'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_padstartstring-length0-chars"></a>`_.padStart([string=''], [length=0], [chars=' '])`
+<a href="#_padstartstring-length0-chars">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13605 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.padstart "See the npm package")
+
+Pads `string` on the left side if it's shorter than `length`. Padding
+characters are truncated if they exceed `length`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to pad.
+2. `[length=0]` *(number)*: The padding length.
+3. `[chars=' ']` *(string)*: The string used as padding.
+
+#### Returns
+*(string)*: Returns the padded string.
+
+#### Example
+```js
+_.padStart('abc', 6);
+// => '   abc'
+
+_.padStart('abc', 6, '_-');
+// => '_-_abc'
+
+_.padStart('abc', 3);
+// => 'abc'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_parseintstring-radix10"></a>`_.parseInt(string, [radix=10])`
+<a href="#_parseintstring-radix10">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13639 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.parseint "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** This method aligns with the
+[ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`.
+
+#### Since
+1.1.0
+#### Arguments
+1. `string` *(string)*: The string to convert.
+2. `[radix=10]` *(number)*: The radix to interpret `value` by.
+
+#### Returns
+*(number)*: Returns the converted integer.
+
+#### Example
+```js
+_.parseInt('08');
+// => 8
+
+_.map(['6', '08', '10'], _.parseInt);
+// => [6, 8, 10]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_repeatstring-n1"></a>`_.repeat([string=''], [n=1])`
+<a href="#_repeatstring-n1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13673 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.repeat "See the npm package")
+
+Repeats the given string `n` times.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to repeat.
+2. `[n=1]` *(number)*: The number of times to repeat the string.
+
+#### Returns
+*(string)*: Returns the repeated string.
+
+#### Example
+```js
+_.repeat('*', 3);
+// => '***'
+
+_.repeat('abc', 2);
+// => 'abcabc'
+
+_.repeat('abc', 0);
+// => ''
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_replacestring-pattern-replacement"></a>`_.replace([string=''], pattern, replacement)`
+<a href="#_replacestring-pattern-replacement">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13701 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.replace "See the npm package")
+
+Replaces matches for `pattern` in `string` with `replacement`.
+<br>
+<br>
+**Note:** This method is based on
+[`String#replace`](https://mdn.io/String/replace).
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to modify.
+2. `pattern` *(RegExp|string)*: The pattern to replace.
+3. `replacement` *(Function|string)*: The match replacement.
+
+#### Returns
+*(string)*: Returns the modified string.
+
+#### Example
+```js
+_.replace('Hi Fred', 'Fred', 'Barney');
+// => 'Hi Barney'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_snakecasestring"></a>`_.snakeCase([string=''])`
+<a href="#_snakecasestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13729 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.snakecase "See the npm package")
+
+Converts `string` to
+[snake case](https://en.wikipedia.org/wiki/Snake_case).
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the snake cased string.
+
+#### Example
+```js
+_.snakeCase('Foo Bar');
+// => 'foo_bar'
+
+_.snakeCase('fooBar');
+// => 'foo_bar'
+
+_.snakeCase('--FOO-BAR--');
+// => 'foo_bar'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_splitstring-separator-limit"></a>`_.split([string=''], separator, [limit])`
+<a href="#_splitstring-separator-limit">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13752 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.split "See the npm package")
+
+Splits `string` by `separator`.
+<br>
+<br>
+**Note:** This method is based on
+[`String#split`](https://mdn.io/String/split).
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to split.
+2. `separator` *(RegExp|string)*: The separator pattern to split by.
+3. `[limit]` *(number)*: The length to truncate results to.
+
+#### Returns
+*(Array)*: Returns the new array of string segments.
+
+#### Example
+```js
+_.split('a-b-c', '-', 2);
+// => ['a', 'b']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_startcasestring"></a>`_.startCase([string=''])`
+<a href="#_startcasestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13794 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.startcase "See the npm package")
+
+Converts `string` to
+[start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage).
+
+#### Since
+3.1.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the start cased string.
+
+#### Example
+```js
+_.startCase('--foo-bar--');
+// => 'Foo Bar'
+
+_.startCase('fooBar');
+// => 'Foo Bar'
+
+_.startCase('__FOO_BAR__');
+// => 'FOO BAR'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_startswithstring-target-position0"></a>`_.startsWith([string=''], [target], [position=0])`
+<a href="#_startswithstring-target-position0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13821 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.startswith "See the npm package")
+
+Checks if `string` starts with the given target string.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to search.
+2. `[target]` *(string)*: The string to search for.
+3. `[position=0]` *(number)*: The position to search from.
+
+#### Returns
+*(boolean)*: Returns `true` if `string` starts with `target`, else `false`.
+
+#### Example
+```js
+_.startsWith('abc', 'a');
+// => true
+
+_.startsWith('abc', 'b');
+// => false
+
+_.startsWith('abc', 'b', 1);
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatestring-options-optionsescape_templatesettingsescape-optionsevaluate_templatesettingsevaluate-optionsimports_templatesettingsimports-optionsinterpolate_templatesettingsinterpolate-optionssourceurllodashtemplatesourcesn-optionsvariableobj"></a>`_.template([string=''], [options={}], [options.escape=_.templateSettings.escape], [options.evaluate=_.templateSettings.evaluate], [options.imports=_.templateSettings.imports], [options.interpolate=_.templateSettings.interpolate], [options.sourceURL='lodash.templateSources[n]'], [options.variable='obj'])`
+<a href="#_templatestring-options-optionsescape_templatesettingsescape-optionsevaluate_templatesettingsevaluate-optionsimports_templatesettingsimports-optionsinterpolate_templatesettingsinterpolate-optionssourceurllodashtemplatesourcesn-optionsvariableobj">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L13930 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.template "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** In the development build `_.template` utilizes
+[sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
+for easier debugging.
+<br>
+<br>
+For more information on precompiling templates see
+[lodash's custom builds documentation](https://lodash.com/custom-builds).
+<br>
+<br>
+For more information on Chrome extension sandboxes see
+[Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval).
+
+#### Since
+0.1.0
+#### Arguments
+1. `[string='']` *(string)*: The template string.
+2. `[options={}]` *(Object)*: The options object.
+3. `[options.escape=_.templateSettings.escape]` *(RegExp)*: The HTML "escape" delimiter.
+4. `[options.evaluate=_.templateSettings.evaluate]` *(RegExp)*: The "evaluate" delimiter.
+5. `[options.imports=_.templateSettings.imports]` *(Object)*: An object to import into the template as free variables.
+6. `[options.interpolate=_.templateSettings.interpolate]` *(RegExp)*: The "interpolate" delimiter.
+7. `[options.sourceURL='lodash.templateSources[n]']` *(string)*: The sourceURL of the compiled template.
+8. `[options.variable='obj']` *(string)*: The data object variable name.
+
+#### Returns
+*(Function)*: Returns the compiled template function.
+
+#### Example
+```js
+// 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 delimiter as an alternative to the default "interpolate" delimiter.
+var compiled = _.template('hello ${ user }!');
+compiled({ 'user': 'pebbles' });
+// => 'hello pebbles!'
+
+// Use custom template delimiters.
+_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
+var compiled = _.template('hello {{ user }}!');
+compiled({ 'user': 'mustache' });
+// => 'hello mustache!'
+
+// 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 the `source` property to inline compiled templates for meaningful
+// line numbers in error messages and stack traces.
+fs.writeFileSync(path.join(cwd, 'jst.js'), '\
+  var JST = {\
+    "main": ' + _.template(mainText).source + '\
+  };\
+');
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_tolowerstring"></a>`_.toLower([string=''])`
+<a href="#_tolowerstring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14059 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.tolower "See the npm package")
+
+Converts `string`, as a whole, to lower case just like
+[String#toLowerCase](https://mdn.io/toLowerCase).
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the lower cased string.
+
+#### Example
+```js
+_.toLower('--Foo-Bar--');
+// => '--foo-bar--'
+
+_.toLower('fooBar');
+// => 'foobar'
+
+_.toLower('__FOO_BAR__');
+// => '__foo_bar__'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_toupperstring"></a>`_.toUpper([string=''])`
+<a href="#_toupperstring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14084 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.toupper "See the npm package")
+
+Converts `string`, as a whole, to upper case just like
+[String#toUpperCase](https://mdn.io/toUpperCase).
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the upper cased string.
+
+#### Example
+```js
+_.toUpper('--foo-bar--');
+// => '--FOO-BAR--'
+
+_.toUpper('fooBar');
+// => 'FOOBAR'
+
+_.toUpper('__foo_bar__');
+// => '__FOO_BAR__'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_trimstring-charswhitespace"></a>`_.trim([string=''], [chars=whitespace])`
+<a href="#_trimstring-charswhitespace">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14110 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.trim "See the npm package")
+
+Removes leading and trailing whitespace or specified characters from `string`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to trim.
+2. `[chars=whitespace]` *(string)*: The characters to trim.
+
+#### Returns
+*(string)*: Returns the trimmed string.
+
+#### Example
+```js
+_.trim('  abc  ');
+// => 'abc'
+
+_.trim('-_-abc-_-', '_-');
+// => 'abc'
+
+_.map(['  foo  ', '  bar  '], _.trim);
+// => ['foo', 'bar']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_trimendstring-charswhitespace"></a>`_.trimEnd([string=''], [chars=whitespace])`
+<a href="#_trimendstring-charswhitespace">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14145 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.trimend "See the npm package")
+
+Removes trailing whitespace or specified characters from `string`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to trim.
+2. `[chars=whitespace]` *(string)*: The characters to trim.
+
+#### Returns
+*(string)*: Returns the trimmed string.
+
+#### Example
+```js
+_.trimEnd('  abc  ');
+// => '  abc'
+
+_.trimEnd('-_-abc-_-', '_-');
+// => '-_-abc'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_trimstartstring-charswhitespace"></a>`_.trimStart([string=''], [chars=whitespace])`
+<a href="#_trimstartstring-charswhitespace">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14178 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.trimstart "See the npm package")
+
+Removes leading whitespace or specified characters from `string`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to trim.
+2. `[chars=whitespace]` *(string)*: The characters to trim.
+
+#### Returns
+*(string)*: Returns the trimmed string.
+
+#### Example
+```js
+_.trimStart('  abc  ');
+// => 'abc  '
+
+_.trimStart('-_-abc-_-', '_-');
+// => 'abc-_-'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_truncatestring-options-optionslength30-optionsomission-optionsseparator"></a>`_.truncate([string=''], [options={}], [options.length=30], [options.omission='...'], [options.separator])`
+<a href="#_truncatestring-options-optionslength30-optionsomission-optionsseparator">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14229 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.truncate "See the npm package")
+
+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 "...".
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to truncate.
+2. `[options={}]` *(Object)*: The options object.
+3. `[options.length=30]` *(number)*: The maximum string length.
+4. `[options.omission='...']` *(string)*: The string to indicate text is omitted.
+5. `[options.separator]` *(RegExp|string)*: The separator pattern to truncate to.
+
+#### Returns
+*(string)*: Returns the truncated string.
+
+#### Example
+```js
+_.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 [...]'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_unescapestring"></a>`_.unescape([string=''])`
+<a href="#_unescapestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14304 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.unescape "See the npm package")
+
+The inverse of `_.escape`; this method converts the HTML entities
+`&amp;`, `&lt;`, `&gt;`, `&quot;`, `&#39;`, and `&#96;` in `string` to
+their corresponding characters.
+<br>
+<br>
+**Note:** No other HTML entities are unescaped. To unescape additional
+HTML entities use a third-party library like [_he_](https://mths.be/he).
+
+#### Since
+0.6.0
+#### Arguments
+1. `[string='']` *(string)*: The string to unescape.
+
+#### Returns
+*(string)*: Returns the unescaped string.
+
+#### Example
+```js
+_.unescape('fred, barney, &amp; pebbles');
+// => 'fred, barney, & pebbles'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_uppercasestring"></a>`_.upperCase([string=''])`
+<a href="#_uppercasestring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14331 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.uppercase "See the npm package")
+
+Converts `string`, as space separated words, to upper case.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the upper cased string.
+
+#### Example
+```js
+_.upperCase('--foo-bar');
+// => 'FOO BAR'
+
+_.upperCase('fooBar');
+// => 'FOO BAR'
+
+_.upperCase('__foo_bar__');
+// => 'FOO BAR'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_upperfirststring"></a>`_.upperFirst([string=''])`
+<a href="#_upperfirststring">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14352 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.upperfirst "See the npm package")
+
+Converts the first character of `string` to upper case.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to convert.
+
+#### Returns
+*(string)*: Returns the converted string.
+
+#### Example
+```js
+_.upperFirst('fred');
+// => 'Fred'
+
+_.upperFirst('FRED');
+// => 'FRED'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_wordsstring-pattern"></a>`_.words([string=''], [pattern])`
+<a href="#_wordsstring-pattern">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14373 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.words "See the npm package")
+
+Splits `string` into an array of its words.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[string='']` *(string)*: The string to inspect.
+2. `[pattern]` *(RegExp|string)*: The pattern to match words.
+
+#### Returns
+*(Array)*: Returns the words of `string`.
+
+#### Example
+```js
+_.words('fred, barney, & pebbles');
+// => ['fred', 'barney', 'pebbles']
+
+_.words('fred, barney, & pebbles', /[^, ]+/g);
+// => ['fred', 'barney', '&', 'pebbles']
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `“Util” Methods`
+
+<!-- div -->
+
+### <a id="_attemptfunc-args"></a>`_.attempt(func, [args])`
+<a href="#_attemptfunc-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14407 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.attempt "See the npm package")
+
+Attempts to invoke `func`, returning either the result or the caught error
+object. Any additional arguments are provided to `func` when it's invoked.
+
+#### Since
+3.0.0
+#### Arguments
+1. `func` *(Function)*: The function to attempt.
+2. `[args]` *(...&#42;)*: The arguments to invoke `func` with.
+
+#### Returns
+*(&#42;)*: Returns the `func` result or error object.
+
+#### Example
+```js
+// Avoid throwing errors for invalid selectors.
+var elements = _.attempt(function(selector) {
+  return document.querySelectorAll(selector);
+}, '>_>');
+
+if (_.isError(elements)) {
+  elements = [];
+}
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_bindallobject-methodnames"></a>`_.bindAll(object, methodNames)`
+<a href="#_bindallobject-methodnames">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14441 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.bindall "See the npm package")
+
+Binds methods of an object to the object itself, overwriting the existing
+method.
+<br>
+<br>
+**Note:** This method doesn't set the "length" property of bound functions.
+
+#### Since
+0.1.0
+#### Arguments
+1. `object` *(Object)*: The object to bind and assign the bound methods to.
+2. `methodNames` *(...(string|string&#91;&#93;))*: The object method names to bind.
+
+#### Returns
+*(Object)*: Returns `object`.
+
+#### Example
+```js
+var view = {
+  'label': 'docs',
+  'onClick': function() {
+    console.log('clicked ' + this.label);
+  }
+};
+
+_.bindAll(view, 'onClick');
+jQuery(element).on('click', view.onClick);
+// => Logs 'clicked docs' when clicked.
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_condpairs"></a>`_.cond(pairs)`
+<a href="#_condpairs">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14478 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.cond "See the npm package")
+
+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.
+
+#### Since
+4.0.0
+#### Arguments
+1. `pairs` *(Array)*: The predicate-function pairs.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var func = _.cond([
+  [_.matches({ 'a': 1 }),           _.constant('matches A')],
+  [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+  [_.constant(true),                _.constant('no match')]
+]);
+
+func({ 'a': 1, 'b': 2 });
+// => 'matches A'
+
+func({ 'a': 0, 'b': 1 });
+// => 'matches B'
+
+func({ 'a': '1', 'b': '2' });
+// => 'no match'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_conformssource"></a>`_.conforms(source)`
+<a href="#_conformssource">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14521 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.conforms "See the npm package")
+
+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`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `source` *(Object)*: The object of property predicates to conform to.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var users = [
+  { 'user': 'barney', 'age': 36 },
+  { 'user': 'fred',   'age': 40 }
+];
+
+_.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
+// => [{ 'user': 'fred', 'age': 40 }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_constantvalue"></a>`_.constant(value)`
+<a href="#_constantvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14542 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.constant "See the npm package")
+
+Creates a function that returns `value`.
+
+#### Since
+2.4.0
+#### Arguments
+1. `value` *(&#42;)*: The value to return from the new function.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var object = { 'user': 'fred' };
+var getter = _.constant(object);
+
+getter() === object;
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flowfuncs"></a>`_.flow([funcs])`
+<a href="#_flowfuncs">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14570 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flow "See the npm package")
+
+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.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[funcs]` *(...(Function|Function&#91;&#93;))*: Functions to invoke.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+function square(n) {
+  return n * n;
+}
+
+var addSquare = _.flow(_.add, square);
+addSquare(1, 2);
+// => 9
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_flowrightfuncs"></a>`_.flowRight([funcs])`
+<a href="#_flowrightfuncs">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14593 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.flowright "See the npm package")
+
+This method is like `_.flow` except that it creates a function that
+invokes the given functions from right to left.
+
+#### Since
+3.0.0
+#### Arguments
+1. `[funcs]` *(...(Function|Function&#91;&#93;))*: Functions to invoke.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+function square(n) {
+  return n * n;
+}
+
+var addSquare = _.flowRight(square, _.add);
+addSquare(1, 2);
+// => 9
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_identityvalue"></a>`_.identity(value)`
+<a href="#_identityvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14611 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.identity "See the npm package")
+
+This method returns the first argument given to it.
+
+#### Since
+0.1.0
+#### Arguments
+1. `value` *(&#42;)*: Any value.
+
+#### Returns
+*(&#42;)*: Returns `value`.
+
+#### Example
+```js
+var object = { 'user': 'fred' };
+
+_.identity(object) === object;
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_iterateefunc_identity"></a>`_.iteratee([func=_.identity])`
+<a href="#_iterateefunc_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14657 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.iteratee "See the npm package")
+
+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`.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[func=_.identity]` *(&#42;)*: The value to convert to a callback.
+
+#### Returns
+*(Function)*: Returns the callback.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_matchessource"></a>`_.matches(source)`
+<a href="#_matchessource">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14685 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.matches "See the npm package")
+
+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`. The created function is equivalent to
+`_.isMatch` with a `source` partially applied.
+<br>
+<br>
+**Note:** This method supports comparing the same values as `_.isEqual`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `source` *(Object)*: The object of property values to match.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var users = [
+  { 'user': 'barney', 'age': 36, 'active': true },
+  { 'user': 'fred',   'age': 40, 'active': false }
+];
+
+_.filter(users, _.matches({ 'age': 40, 'active': false }));
+// => [{ 'user': 'fred', 'age': 40, 'active': false }]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_matchespropertypath-srcvalue"></a>`_.matchesProperty(path, srcValue)`
+<a href="#_matchespropertypath-srcvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14713 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package")
+
+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`.
+<br>
+<br>
+**Note:** This method supports comparing the same values as `_.isEqual`.
+
+#### Since
+3.2.0
+#### Arguments
+1. `path` *(Array|string)*: The path of the property to get.
+2. `srcValue` *(&#42;)*: The value to match.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var users = [
+  { 'user': 'barney' },
+  { 'user': 'fred' }
+];
+
+_.find(users, _.matchesProperty('user', 'fred'));
+// => { 'user': 'fred' }
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_methodpath-args"></a>`_.method(path, [args])`
+<a href="#_methodpath-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14741 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.method "See the npm package")
+
+Creates a function that invokes the method at `path` of a given object.
+Any additional arguments are provided to the invoked method.
+
+#### Since
+3.7.0
+#### Arguments
+1. `path` *(Array|string)*: The path of the method to invoke.
+2. `[args]` *(...&#42;)*: The arguments to invoke the method with.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var objects = [
+  { 'a': { 'b': _.constant(2) } },
+  { 'a': { 'b': _.constant(1) } }
+];
+
+_.map(objects, _.method('a.b'));
+// => [2, 1]
+
+_.map(objects, _.method(['a', 'b']));
+// => [2, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_methodofobject-args"></a>`_.methodOf(object, [args])`
+<a href="#_methodofobject-args">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14770 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.methodof "See the npm package")
+
+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.
+
+#### Since
+3.7.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+2. `[args]` *(...&#42;)*: The arguments to invoke the method with.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_mixinobjectlodash-source-options-optionschaintrue"></a>`_.mixin([object=lodash], source, [options={}], [options.chain=true])`
+<a href="#_mixinobjectlodash-source-options-optionschaintrue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14812 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.mixin "See the npm package")
+
+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.
+<br>
+<br>
+**Note:** Use `_.runInContext` to create a pristine `lodash` function to
+avoid conflicts caused by modifying the original.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[object=lodash]` *(Function|Object)*: The destination object.
+2. `source` *(Object)*: The object of functions to add.
+3. `[options={}]` *(Object)*: The options object.
+4. `[options.chain=true]` *(boolean)*: Specify whether mixins are chainable.
+
+#### Returns
+*(&#42;)*: Returns `object`.
+
+#### Example
+```js
+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']
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_noconflict"></a>`_.noConflict()`
+<a href="#_noconflict">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14861 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.noconflict "See the npm package")
+
+Reverts the `_` variable to its previous value and returns a reference to
+the `lodash` function.
+
+#### Since
+0.1.0
+#### Returns
+*(Function)*: Returns the `lodash` function.
+
+#### Example
+```js
+var lodash = _.noConflict();
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_noop"></a>`_.noop()`
+<a href="#_noop">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14883 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.noop "See the npm package")
+
+A no-operation function that returns `undefined` regardless of the
+arguments it receives.
+
+#### Since
+2.3.0
+#### Example
+```js
+var object = { 'user': 'fred' };
+
+_.noop(object) === undefined;
+// => true
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_nthargn0"></a>`_.nthArg([n=0])`
+<a href="#_nthargn0">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14907 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.ntharg "See the npm package")
+
+Creates a function that returns its nth argument. If `n` is negative,
+the nth argument from the end is returned.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[n=0]` *(number)*: The index of the argument to return.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var func = _.nthArg(1);
+func('a', 'b', 'c', 'd');
+// => 'b'
+
+var func = _.nthArg(-2);
+func('a', 'b', 'c', 'd');
+// => 'c'
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_overiteratees_identity"></a>`_.over([iteratees=[_.identity]])`
+<a href="#_overiteratees_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14932 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.over "See the npm package")
+
+Creates a function that invokes `iteratees` with the arguments it receives
+and returns their results.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[iteratees=[_.identity]]` *(...(Array|Array&#91;&#93;|Function|Function&#91;&#93;|Object|Object&#91;&#93;|string|string&#91;&#93;))*: The iteratees to invoke.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var func = _.over(Math.max, Math.min);
+
+func(1, 2, 3, 4);
+// => [4, 1]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_overeverypredicates_identity"></a>`_.overEvery([predicates=[_.identity]])`
+<a href="#_overeverypredicates_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14958 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.overevery "See the npm package")
+
+Creates a function that checks if **all** of the `predicates` return
+truthy when invoked with the arguments it receives.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[predicates=[_.identity]]` *(...(Array|Array&#91;&#93;|Function|Function&#91;&#93;|Object|Object&#91;&#93;|string|string&#91;&#93;))*: The predicates to check.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var func = _.overEvery(Boolean, isFinite);
+
+func('1');
+// => true
+
+func(null);
+// => false
+
+func(NaN);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_oversomepredicates_identity"></a>`_.overSome([predicates=[_.identity]])`
+<a href="#_oversomepredicates_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L14984 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.oversome "See the npm package")
+
+Creates a function that checks if **any** of the `predicates` return
+truthy when invoked with the arguments it receives.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[predicates=[_.identity]]` *(...(Array|Array&#91;&#93;|Function|Function&#91;&#93;|Object|Object&#91;&#93;|string|string&#91;&#93;))*: The predicates to check.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+var func = _.overSome(Boolean, isFinite);
+
+func('1');
+// => true
+
+func(null);
+// => true
+
+func(NaN);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_propertypath"></a>`_.property(path)`
+<a href="#_propertypath">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15008 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.property "See the npm package")
+
+Creates a function that returns the value at `path` of a given object.
+
+#### Since
+2.4.0
+#### Arguments
+1. `path` *(Array|string)*: The path of the property to get.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_propertyofobject"></a>`_.propertyOf(object)`
+<a href="#_propertyofobject">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15033 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.propertyof "See the npm package")
+
+The opposite of `_.property`; this method creates a function that returns
+the value at a given path of `object`.
+
+#### Since
+3.0.0
+#### Arguments
+1. `object` *(Object)*: The object to query.
+
+#### Returns
+*(Function)*: Returns the new function.
+
+#### Example
+```js
+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]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_rangestart0-end-step1"></a>`_.range([start=0], end, [step=1])`
+<a href="#_rangestart0-end-step1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15080 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.range "See the npm package")
+
+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`.
+<br>
+<br>
+**Note:** JavaScript follows the IEEE-754 standard for resolving
+floating-point values which can produce unexpected results.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[start=0]` *(number)*: The start of the range.
+2. `end` *(number)*: The end of the range.
+3. `[step=1]` *(number)*: The value to increment or decrement by.
+
+#### Returns
+*(Array)*: Returns the new array of numbers.
+
+#### Example
+```js
+_.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);
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_rangerightstart0-end-step1"></a>`_.rangeRight([start=0], end, [step=1])`
+<a href="#_rangerightstart0-end-step1">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15118 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.rangeright "See the npm package")
+
+This method is like `_.range` except that it populates values in
+descending order.
+
+#### Since
+4.0.0
+#### Arguments
+1. `[start=0]` *(number)*: The start of the range.
+2. `end` *(number)*: The end of the range.
+3. `[step=1]` *(number)*: The value to increment or decrement by.
+
+#### Returns
+*(Array)*: Returns the new array of numbers.
+
+#### Example
+```js
+_.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);
+// => []
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_runincontextcontextroot"></a>`_.runInContext([context=root])`
+<a href="#_runincontextcontextroot">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1239 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.runincontext "See the npm package")
+
+Create a new pristine `lodash` function using the `context` object.
+
+#### Since
+1.1.0
+#### Arguments
+1. `[context=root]` *(Object)*: The context object.
+
+#### Returns
+*(Function)*: Returns a new `lodash` function.
+
+#### Example
+```js
+_.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
+
+// Use `context` to mock `Date#getTime` use in `_.now`.
+var mock = _.runInContext({
+  'Date': function() {
+    return { 'getTime': getTimeMock };
+  }
+});
+
+// Create a suped-up `defer` in Node.js.
+var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_timesn-iteratee_identity"></a>`_.times(n, [iteratee=_.identity])`
+<a href="#_timesn-iteratee_identity">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15139 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.times "See the npm package")
+
+Invokes the iteratee `n` times, returning an array of the results of
+each invocation. The iteratee is invoked with one argument; *(index)*.
+
+#### Since
+0.1.0
+#### Arguments
+1. `n` *(number)*: The number of times to invoke `iteratee`.
+2. `[iteratee=_.identity]` *(Function)*: The function invoked per iteration.
+
+#### Returns
+*(Array)*: Returns the array of results.
+
+#### Example
+```js
+_.times(3, String);
+// => ['0', '1', '2']
+
+ _.times(4, _.constant(true));
+// => [true, true, true, true]
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_topathvalue"></a>`_.toPath(value)`
+<a href="#_topathvalue">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15183 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.topath "See the npm package")
+
+Converts `value` to a property path array.
+
+#### Since
+4.0.0
+#### Arguments
+1. `value` *(&#42;)*: The value to convert.
+
+#### Returns
+*(Array)*: Returns the new property path array.
+
+#### Example
+```js
+_.toPath('a.b.c');
+// => ['a', 'b', 'c']
+
+_.toPath('a[0].b.c');
+// => ['a', '0', 'b', 'c']
+
+var path = ['a', 'b', 'c'],
+    newPath = _.toPath(path);
+
+console.log(newPath);
+// => ['a', 'b', 'c']
+
+console.log(path === newPath);
+// => false
+```
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_uniqueidprefix"></a>`_.uniqueId([prefix=''])`
+<a href="#_uniqueidprefix">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15207 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.uniqueid "See the npm package")
+
+Generates a unique ID. If `prefix` is given, the ID is appended to it.
+
+#### Since
+0.1.0
+#### Arguments
+1. `[prefix='']` *(string)*: The value to prefix the ID with.
+
+#### Returns
+*(string)*: Returns the unique ID.
+
+#### Example
+```js
+_.uniqueId('contact_');
+// => 'contact_104'
+
+_.uniqueId();
+// => '105'
+```
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Properties`
+
+<!-- div -->
+
+### <a id="_version"></a>`_.VERSION`
+<a href="#_version">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L15894 "View in source") [&#x24C9;][1]
+
+(string): The semantic version number.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatesettings"></a>`_.templateSettings`
+<a href="#_templatesettings">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1502 "View in source") [&#x24C9;][1] [&#x24C3;](https://www.npmjs.com/package/lodash.templatesettings "See the npm package")
+
+(Object): By default, the template delimiters used by lodash are like those in
+embedded Ruby *(ERB)*. Change the following template settings to use
+alternative delimiters.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatesettingsescape"></a>`_.templateSettings.escape`
+<a href="#_templatesettingsescape">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1510 "View in source") [&#x24C9;][1]
+
+(RegExp): Used to detect `data` property values to be HTML-escaped.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatesettingsevaluate"></a>`_.templateSettings.evaluate`
+<a href="#_templatesettingsevaluate">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1518 "View in source") [&#x24C9;][1]
+
+(RegExp): Used to detect code to be evaluated.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatesettingsimports"></a>`_.templateSettings.imports`
+<a href="#_templatesettingsimports">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1542 "View in source") [&#x24C9;][1]
+
+(Object): Used to import variables into the compiled template.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatesettingsinterpolate"></a>`_.templateSettings.interpolate`
+<a href="#_templatesettingsinterpolate">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1526 "View in source") [&#x24C9;][1]
+
+(RegExp): Used to detect `data` property values to inject.
+
+* * *
+
+<!-- /div -->
+
+<!-- div -->
+
+### <a id="_templatesettingsvariable"></a>`_.templateSettings.variable`
+<a href="#_templatesettingsvariable">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1534 "View in source") [&#x24C9;][1]
+
+(string): Used to reference the data object in the template text.
+
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- div -->
+
+## `Methods`
+
+<!-- div -->
+
+### <a id="_templatesettingsimports_"></a>`_.templateSettings.imports._`
+<a href="#_templatesettingsimports_">#</a> [&#x24C8;](https://github.com/lodash/lodash/blob/4.11.2/lodash.js#L1550 "View in source") [&#x24C9;][1]
+
+A reference to the `lodash` function.
+
+* * *
+
+<!-- /div -->
+
+<!-- /div -->
+
+<!-- /div -->
+
+ [1]: #array "Jump back to the TOC."
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_baseConvert.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_baseConvert.js
new file mode 100644
index 0000000..e7e631c
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_baseConvert.js
@@ -0,0 +1,469 @@
+var mapping = require('./_mapping'),
+    mutateMap = mapping.mutate,
+    fallbackHolder = require('./placeholder');
+
+/**
+ * Creates a function, with an arity of `n`, that invokes `func` with the
+ * arguments it receives.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {number} n The arity of the new function.
+ * @returns {Function} Returns the new function.
+ */
+function baseArity(func, n) {
+  return n == 2
+    ? function(a, b) { return func.apply(undefined, arguments); }
+    : function(a) { return func.apply(undefined, arguments); };
+}
+
+/**
+ * Creates a function that invokes `func`, with up to `n` arguments, ignoring
+ * any additional arguments.
+ *
+ * @private
+ * @param {Function} func The function to cap arguments for.
+ * @param {number} n The arity cap.
+ * @returns {Function} Returns the new function.
+ */
+function baseAry(func, n) {
+  return n == 2
+    ? function(a, b) { return func(a, b); }
+    : function(a) { return func(a); };
+}
+
+/**
+ * Creates a clone of `array`.
+ *
+ * @private
+ * @param {Array} array The array to clone.
+ * @returns {Array} Returns the cloned array.
+ */
+function cloneArray(array) {
+  var length = array ? array.length : 0,
+      result = Array(length);
+
+  while (length--) {
+    result[length] = array[length];
+  }
+  return result;
+}
+
+/**
+ * Creates a function that clones a given object using the assignment `func`.
+ *
+ * @private
+ * @param {Function} func The assignment function.
+ * @returns {Function} Returns the new cloner function.
+ */
+function createCloner(func) {
+  return function(object) {
+    return func({}, object);
+  };
+}
+
+/**
+ * Creates a function that wraps `func` and uses `cloner` to clone the first
+ * argument it receives.
+ *
+ * @private
+ * @param {Function} func The function to wrap.
+ * @param {Function} cloner The function to clone arguments.
+ * @returns {Function} Returns the new immutable function.
+ */
+function immutWrap(func, cloner) {
+  return function() {
+    var length = arguments.length;
+    if (!length) {
+      return result;
+    }
+    var args = Array(length);
+    while (length--) {
+      args[length] = arguments[length];
+    }
+    var result = args[0] = cloner.apply(undefined, args);
+    func.apply(undefined, args);
+    return result;
+  };
+}
+
+/**
+ * The base implementation of `convert` which accepts a `util` object of methods
+ * required to perform conversions.
+ *
+ * @param {Object} util The util object.
+ * @param {string} name The name of the function to convert.
+ * @param {Function} func The function to convert.
+ * @param {Object} [options] The options object.
+ * @param {boolean} [options.cap=true] Specify capping iteratee arguments.
+ * @param {boolean} [options.curry=true] Specify currying.
+ * @param {boolean} [options.fixed=true] Specify fixed arity.
+ * @param {boolean} [options.immutable=true] Specify immutable operations.
+ * @param {boolean} [options.rearg=true] Specify rearranging arguments.
+ * @returns {Function|Object} Returns the converted function or object.
+ */
+function baseConvert(util, name, func, options) {
+  var setPlaceholder,
+      isLib = typeof name == 'function',
+      isObj = name === Object(name);
+
+  if (isObj) {
+    options = func;
+    func = name;
+    name = undefined;
+  }
+  if (func == null) {
+    throw new TypeError;
+  }
+  options || (options = {});
+
+  var config = {
+    'cap': 'cap' in options ? options.cap : true,
+    'curry': 'curry' in options ? options.curry : true,
+    'fixed': 'fixed' in options ? options.fixed : true,
+    'immutable': 'immutable' in options ? options.immutable : true,
+    'rearg': 'rearg' in options ? options.rearg : true
+  };
+
+  var forceCurry = ('curry' in options) && options.curry,
+      forceFixed = ('fixed' in options) && options.fixed,
+      forceRearg = ('rearg' in options) && options.rearg,
+      placeholder = isLib ? func : fallbackHolder,
+      pristine = isLib ? func.runInContext() : undefined;
+
+  var helpers = isLib ? func : {
+    'ary': util.ary,
+    'assign': util.assign,
+    'clone': util.clone,
+    'curry': util.curry,
+    'forEach': util.forEach,
+    'isArray': util.isArray,
+    'isFunction': util.isFunction,
+    'iteratee': util.iteratee,
+    'keys': util.keys,
+    'rearg': util.rearg,
+    'spread': util.spread,
+    'toPath': util.toPath
+  };
+
+  var ary = helpers.ary,
+      assign = helpers.assign,
+      clone = helpers.clone,
+      curry = helpers.curry,
+      each = helpers.forEach,
+      isArray = helpers.isArray,
+      isFunction = helpers.isFunction,
+      keys = helpers.keys,
+      rearg = helpers.rearg,
+      spread = helpers.spread,
+      toPath = helpers.toPath;
+
+  var aryMethodKeys = keys(mapping.aryMethod);
+
+  var wrappers = {
+    'castArray': function(castArray) {
+      return function() {
+        var value = arguments[0];
+        return isArray(value)
+          ? castArray(cloneArray(value))
+          : castArray.apply(undefined, arguments);
+      };
+    },
+    'iteratee': function(iteratee) {
+      return function() {
+        var func = arguments[0],
+            arity = arguments[1],
+            result = iteratee(func, arity),
+            length = result.length;
+
+        if (config.cap && typeof arity == 'number') {
+          arity = arity > 2 ? (arity - 2) : 1;
+          return (length && length <= arity) ? result : baseAry(result, arity);
+        }
+        return result;
+      };
+    },
+    'mixin': function(mixin) {
+      return function(source) {
+        var func = this;
+        if (!isFunction(func)) {
+          return mixin(func, Object(source));
+        }
+        var methods = [],
+            methodNames = [];
+
+        each(keys(source), function(key) {
+          var value = source[key];
+          if (isFunction(value)) {
+            methodNames.push(key);
+            methods.push(func.prototype[key]);
+          }
+        });
+
+        mixin(func, Object(source));
+
+        each(methodNames, function(methodName, index) {
+          var method = methods[index];
+          if (isFunction(method)) {
+            func.prototype[methodName] = method;
+          } else {
+            delete func.prototype[methodName];
+          }
+        });
+        return func;
+      };
+    },
+    'runInContext': function(runInContext) {
+      return function(context) {
+        return baseConvert(util, runInContext(context), options);
+      };
+    }
+  };
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Creates a clone of `object` by `path`.
+   *
+   * @private
+   * @param {Object} object The object to clone.
+   * @param {Array|string} path The path to clone by.
+   * @returns {Object} Returns the cloned object.
+   */
+  function cloneByPath(object, path) {
+    path = toPath(path);
+
+    var index = -1,
+        length = path.length,
+        result = clone(Object(object)),
+        nested = result;
+
+    while (nested != null && ++index < length) {
+      var key = path[index],
+          value = nested[key];
+
+      if (value != null) {
+        nested[key] = clone(Object(value));
+      }
+      nested = nested[key];
+    }
+    return result;
+  }
+
+  /**
+   * Converts `lodash` to an immutable auto-curried iteratee-first data-last
+   * version with conversion `options` applied.
+   *
+   * @param {Object} [options] The options object. See `baseConvert` for more details.
+   * @returns {Function} Returns the converted `lodash`.
+   */
+  function convertLib(options) {
+    return _.runInContext.convert(options)(undefined);
+  }
+
+  /**
+   * Create a converter function for `func` of `name`.
+   *
+   * @param {string} name The name of the function to convert.
+   * @param {Function} func The function to convert.
+   * @returns {Function} Returns the new converter function.
+   */
+  function createConverter(name, func) {
+    var oldOptions = options;
+    return function(options) {
+      var newUtil = isLib ? pristine : helpers,
+          newFunc = isLib ? pristine[name] : func,
+          newOptions = assign(assign({}, oldOptions), options);
+
+      return baseConvert(newUtil, name, newFunc, newOptions);
+    };
+  }
+
+  /**
+   * Creates a function that wraps `func` to invoke its iteratee, with up to `n`
+   * arguments, ignoring any additional arguments.
+   *
+   * @private
+   * @param {Function} func The function to cap iteratee arguments for.
+   * @param {number} n The arity cap.
+   * @returns {Function} Returns the new function.
+   */
+  function iterateeAry(func, n) {
+    return overArg(func, function(func) {
+      return typeof func == 'function' ? baseAry(func, n) : func;
+    });
+  }
+
+  /**
+   * Creates a function that wraps `func` to invoke its iteratee 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.
+   *
+   * @private
+   * @param {Function} func The function to rearrange iteratee arguments for.
+   * @param {number[]} indexes The arranged argument indexes.
+   * @returns {Function} Returns the new function.
+   */
+  function iterateeRearg(func, indexes) {
+    return overArg(func, function(func) {
+      var n = indexes.length;
+      return baseArity(rearg(baseAry(func, n), indexes), n);
+    });
+  }
+
+  /**
+   * Creates a function that invokes `func` with its first argument passed
+   * thru `transform`.
+   *
+   * @private
+   * @param {Function} func The function to wrap.
+   * @param {...Function} transform The functions to transform the first argument.
+   * @returns {Function} Returns the new function.
+   */
+  function overArg(func, transform) {
+    return function() {
+      var length = arguments.length;
+      if (!length) {
+        return func();
+      }
+      var args = Array(length);
+      while (length--) {
+        args[length] = arguments[length];
+      }
+      var index = config.rearg ? 0 : (length - 1);
+      args[index] = transform(args[index]);
+      return func.apply(undefined, args);
+    };
+  }
+
+  /**
+   * Creates a function that wraps `func` and applys the conversions
+   * rules by `name`.
+   *
+   * @private
+   * @param {string} name The name of the function to wrap.
+   * @param {Function} func The function to wrap.
+   * @returns {Function} Returns the converted function.
+   */
+  function wrap(name, func) {
+    name = mapping.aliasToReal[name] || name;
+
+    var result,
+        wrapped = func,
+        wrapper = wrappers[name];
+
+    if (wrapper) {
+      wrapped = wrapper(func);
+    }
+    else if (config.immutable) {
+      if (mutateMap.array[name]) {
+        wrapped = immutWrap(func, cloneArray);
+      }
+      else if (mutateMap.object[name]) {
+        wrapped = immutWrap(func, createCloner(func));
+      }
+      else if (mutateMap.set[name]) {
+        wrapped = immutWrap(func, cloneByPath);
+      }
+    }
+    each(aryMethodKeys, function(aryKey) {
+      each(mapping.aryMethod[aryKey], function(otherName) {
+        if (name == otherName) {
+          var aryN = !isLib && mapping.iterateeAry[name],
+              reargIndexes = mapping.iterateeRearg[name],
+              spreadStart = mapping.methodSpread[name];
+
+          result = wrapped;
+          if (config.fixed && (forceFixed || !mapping.skipFixed[name])) {
+            result = spreadStart === undefined
+              ? ary(result, aryKey)
+              : spread(result, spreadStart);
+          }
+          if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) {
+            result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]);
+          }
+          if (config.cap) {
+            if (reargIndexes) {
+              result = iterateeRearg(result, reargIndexes);
+            } else if (aryN) {
+              result = iterateeAry(result, aryN);
+            }
+          }
+          if (forceCurry || (config.curry && aryKey > 1)) {
+            forceCurry  && console.log(forceCurry, name);
+            result = curry(result, aryKey);
+          }
+          return false;
+        }
+      });
+      return !result;
+    });
+
+    result || (result = wrapped);
+    if (result == func) {
+      result = forceCurry ? curry(result, 1) : function() {
+        return func.apply(this, arguments);
+      };
+    }
+    result.convert = createConverter(name, func);
+    if (mapping.placeholder[name]) {
+      setPlaceholder = true;
+      result.placeholder = func.placeholder = placeholder;
+    }
+    return result;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  if (!isObj) {
+    return wrap(name, func);
+  }
+  var _ = func;
+
+  // Convert methods by ary cap.
+  var pairs = [];
+  each(aryMethodKeys, function(aryKey) {
+    each(mapping.aryMethod[aryKey], function(key) {
+      var func = _[mapping.remap[key] || key];
+      if (func) {
+        pairs.push([key, wrap(key, func)]);
+      }
+    });
+  });
+
+  // Convert remaining methods.
+  each(keys(_), function(key) {
+    var func = _[key];
+    if (typeof func == 'function') {
+      var length = pairs.length;
+      while (length--) {
+        if (pairs[length][0] == key) {
+          return;
+        }
+      }
+      func.convert = createConverter(key, func);
+      pairs.push([key, func]);
+    }
+  });
+
+  // Assign to `_` leaving `_.prototype` unchanged to allow chaining.
+  each(pairs, function(pair) {
+    _[pair[0]] = pair[1];
+  });
+
+  _.convert = convertLib;
+  if (setPlaceholder) {
+    _.placeholder = placeholder;
+  }
+  // Assign aliases.
+  each(keys(_), function(key) {
+    each(mapping.realToAlias[key] || [], function(alias) {
+      _[alias] = _[key];
+    });
+  });
+
+  return _;
+}
+
+module.exports = baseConvert;
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_convertBrowser.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_convertBrowser.js
new file mode 100644
index 0000000..1874a54
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_convertBrowser.js
@@ -0,0 +1,18 @@
+var baseConvert = require('./_baseConvert');
+
+/**
+ * Converts `lodash` to an immutable auto-curried iteratee-first data-last
+ * version with conversion `options` applied.
+ *
+ * @param {Function} lodash The lodash function to convert.
+ * @param {Object} [options] The options object. See `baseConvert` for more details.
+ * @returns {Function} Returns the converted `lodash`.
+ */
+function browserConvert(lodash, options) {
+  return baseConvert(lodash, lodash, options);
+}
+
+if (typeof _ == 'function') {
+  _ = browserConvert(_.runInContext());
+}
+module.exports = browserConvert;
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_mapping.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_mapping.js
new file mode 100644
index 0000000..18a3196
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/_mapping.js
@@ -0,0 +1,290 @@
+/** Used to map aliases to their real names. */
+exports.aliasToReal = {
+
+  // Lodash aliases.
+  'each': 'forEach',
+  'eachRight': 'forEachRight',
+  'entries': 'toPairs',
+  'entriesIn': 'toPairsIn',
+  'extend': 'assignIn',
+  'extendWith': 'assignInWith',
+  'first': 'head',
+
+  // Ramda aliases.
+  '__': 'placeholder',
+  'all': 'every',
+  'allPass': 'overEvery',
+  'always': 'constant',
+  'any': 'some',
+  'anyPass': 'overSome',
+  'apply': 'spread',
+  'assoc': 'set',
+  'assocPath': 'set',
+  'complement': 'negate',
+  'compose': 'flowRight',
+  'contains': 'includes',
+  'dissoc': 'unset',
+  'dissocPath': 'unset',
+  'equals': 'isEqual',
+  'identical': 'eq',
+  'init': 'initial',
+  'invertObj': 'invert',
+  'juxt': 'over',
+  'omitAll': 'omit',
+  'nAry': 'ary',
+  'path': 'get',
+  'pathEq': 'matchesProperty',
+  'pathOr': 'getOr',
+  'paths': 'at',
+  'pickAll': 'pick',
+  'pipe': 'flow',
+  'pluck': 'map',
+  'prop': 'get',
+  'propEq': 'matchesProperty',
+  'propOr': 'getOr',
+  'props': 'at',
+  'unapply': 'rest',
+  'unnest': 'flatten',
+  'useWith': 'overArgs',
+  'whereEq': 'filter',
+  'zipObj': 'zipObject'
+};
+
+/** Used to map ary to method names. */
+exports.aryMethod = {
+  '1': [
+    'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor',
+    'flow', 'flowRight', 'fromPairs', 'invert', 'iteratee', 'memoize', 'method',
+    'methodOf', 'mixin', 'over', 'overEvery', 'overSome', 'rest', 'reverse',
+    'round', 'runInContext', 'spread', 'template', 'trim', 'trimEnd', 'trimStart',
+    'uniqueId', 'words'
+  ],
+  '2': [
+    'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindAll',
+    'bindKey', 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN',
+    'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference',
+    'divide', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith',
+    'eq', 'every', 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast',
+    'findLastIndex', 'findLastKey', 'flatMap', 'flatMapDeep', 'flattenDepth',
+    'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight',
+    'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', 'includes', 'indexOf',
+    'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch',
+    'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues',
+    'matchesProperty', 'maxBy', 'meanBy', 'merge', 'minBy', 'multiply', 'nth',
+    'omit', 'omitBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt',
+    'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll',
+    'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove',
+    'repeat', 'restFrom', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex',
+    'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy',
+    'split', 'spreadFrom', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight',
+    'takeRightWhile', 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars',
+    'trimCharsEnd', 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith',
+    'unset', 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject',
+    'zipObjectDeep'
+  ],
+  '3': [
+    'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith',
+    'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'invokeArgs',
+    'invokeArgsMap', 'isEqualWith', 'isMatchWith', 'flatMapDepth', 'mergeWith',
+    'orderBy', 'padChars', 'padCharsEnd', 'padCharsStart', 'pullAllBy',
+    'pullAllWith', 'reduce', 'reduceRight', 'replace', 'set', 'slice',
+    'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', 'unionWith',
+    'update', 'xorBy', 'xorWith', 'zipWith'
+  ],
+  '4': [
+    'fill', 'setWith', 'updateWith'
+  ]
+};
+
+/** Used to map ary to rearg configs. */
+exports.aryRearg = {
+  '2': [1, 0],
+  '3': [2, 0, 1],
+  '4': [3, 2, 0, 1]
+};
+
+/** Used to map method names to their iteratee ary. */
+exports.iterateeAry = {
+  'dropRightWhile': 1,
+  'dropWhile': 1,
+  'every': 1,
+  'filter': 1,
+  'find': 1,
+  'findIndex': 1,
+  'findKey': 1,
+  'findLast': 1,
+  'findLastIndex': 1,
+  'findLastKey': 1,
+  'flatMap': 1,
+  'flatMapDeep': 1,
+  'flatMapDepth': 1,
+  'forEach': 1,
+  'forEachRight': 1,
+  'forIn': 1,
+  'forInRight': 1,
+  'forOwn': 1,
+  'forOwnRight': 1,
+  'map': 1,
+  'mapKeys': 1,
+  'mapValues': 1,
+  'partition': 1,
+  'reduce': 2,
+  'reduceRight': 2,
+  'reject': 1,
+  'remove': 1,
+  'some': 1,
+  'takeRightWhile': 1,
+  'takeWhile': 1,
+  'times': 1,
+  'transform': 2
+};
+
+/** Used to map method names to iteratee rearg configs. */
+exports.iterateeRearg = {
+  'mapKeys': [1]
+};
+
+/** Used to map method names to rearg configs. */
+exports.methodRearg = {
+  'assignInWith': [1, 2, 0],
+  'assignWith': [1, 2, 0],
+  'getOr': [2, 1, 0],
+  'isEqualWith': [1, 2, 0],
+  'isMatchWith': [2, 1, 0],
+  'mergeWith': [1, 2, 0],
+  'padChars': [2, 1, 0],
+  'padCharsEnd': [2, 1, 0],
+  'padCharsStart': [2, 1, 0],
+  'pullAllBy': [2, 1, 0],
+  'pullAllWith': [2, 1, 0],
+  'setWith': [3, 1, 2, 0],
+  'sortedIndexBy': [2, 1, 0],
+  'sortedLastIndexBy': [2, 1, 0],
+  'updateWith': [3, 1, 2, 0],
+  'zipWith': [1, 2, 0]
+};
+
+/** Used to map method names to spread configs. */
+exports.methodSpread = {
+  'invokeArgs': 2,
+  'invokeArgsMap': 2,
+  'partial': 1,
+  'partialRight': 1,
+  'without': 1
+};
+
+/** Used to identify methods which mutate arrays or objects. */
+exports.mutate = {
+  'array': {
+    'fill': true,
+    'pull': true,
+    'pullAll': true,
+    'pullAllBy': true,
+    'pullAllWith': true,
+    'pullAt': true,
+    'remove': true,
+    'reverse': true
+  },
+  'object': {
+    'assign': true,
+    'assignIn': true,
+    'assignInWith': true,
+    'assignWith': true,
+    'defaults': true,
+    'defaultsDeep': true,
+    'merge': true,
+    'mergeWith': true
+  },
+  'set': {
+    'set': true,
+    'setWith': true,
+    'unset': true,
+    'update': true,
+    'updateWith': true
+  }
+};
+
+/** Used to track methods with placeholder support */
+exports.placeholder = {
+  'bind': true,
+  'bindKey': true,
+  'curry': true,
+  'curryRight': true,
+  'partial': true,
+  'partialRight': true
+};
+
+/** Used to map real names to their aliases. */
+exports.realToAlias = (function() {
+  var hasOwnProperty = Object.prototype.hasOwnProperty,
+      object = exports.aliasToReal,
+      result = {};
+
+  for (var key in object) {
+    var value = object[key];
+    if (hasOwnProperty.call(result, value)) {
+      result[value].push(key);
+    } else {
+      result[value] = [key];
+    }
+  }
+  return result;
+}());
+
+/** Used to map method names to other names. */
+exports.remap = {
+  'curryN': 'curry',
+  'curryRightN': 'curryRight',
+  'getOr': 'get',
+  'invokeArgs': 'invoke',
+  'invokeArgsMap': 'invokeMap',
+  'padChars': 'pad',
+  'padCharsEnd': 'padEnd',
+  'padCharsStart': 'padStart',
+  'restFrom': 'rest',
+  'spreadFrom': 'spread',
+  'trimChars': 'trim',
+  'trimCharsEnd': 'trimEnd',
+  'trimCharsStart': 'trimStart'
+};
+
+/** Used to track methods that skip fixing their arity. */
+exports.skipFixed = {
+  'castArray': true,
+  'flow': true,
+  'flowRight': true,
+  'iteratee': true,
+  'mixin': true,
+  'runInContext': true
+};
+
+/** Used to track methods that skip rearranging arguments. */
+exports.skipRearg = {
+  'add': true,
+  'assign': true,
+  'assignIn': true,
+  'bind': true,
+  'bindKey': true,
+  'concat': true,
+  'difference': true,
+  'divide': true,
+  'eq': true,
+  'gt': true,
+  'gte': true,
+  'isEqual': true,
+  'lt': true,
+  'lte': true,
+  'matchesProperty': true,
+  'merge': true,
+  'multiply': true,
+  'overArgs': true,
+  'partial': true,
+  'partialRight': true,
+  'random': true,
+  'range': true,
+  'rangeRight': true,
+  'subtract': true,
+  'without': true,
+  'zip': true,
+  'zipObject': true
+};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/placeholder.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/placeholder.js
new file mode 100644
index 0000000..1ce1739
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/fp/placeholder.js
@@ -0,0 +1,6 @@
+/**
+ * The default argument placeholder value for methods.
+ *
+ * @type {Object}
+ */
+module.exports = {};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/file.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/file.js
new file mode 100644
index 0000000..9f9016f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/file.js
@@ -0,0 +1,71 @@
+'use strict';
+
+var _ = require('lodash'),
+    fs = require('fs-extra'),
+    glob = require('glob'),
+    path = require('path');
+
+var minify = require('../common/minify.js');
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Creates a [fs.copy](https://github.com/jprichardson/node-fs-extra#copy)
+ * function with `srcPath` and `destPath` partially applied.
+ *
+ * @memberOf file
+ * @param {string} srcPath The path of the file to copy.
+ * @param {string} destPath The path to copy the file to.
+ * @returns {Function} Returns the partially applied function.
+ */
+function copy(srcPath, destPath) {
+  return _.partial(fs.copy, srcPath, destPath);
+}
+
+/**
+ * Creates an object of compiled template and base name pairs that match `pattern`.
+ *
+ * @memberOf file
+ * @param {string} pattern The glob pattern to be match.
+ * @returns {Object} Returns the object of compiled templates.
+ */
+function globTemplate(pattern) {
+  return _.transform(glob.sync(pattern), function(result, filePath) {
+    var key = path.basename(filePath, path.extname(filePath));
+    result[key] = _.template(fs.readFileSync(filePath, 'utf8'));
+  }, {});
+}
+
+/**
+ * Creates a `minify` function with `srcPath` and `destPath` partially applied.
+ *
+ * @memberOf file
+ * @param {string} srcPath The path of the file to minify.
+ * @param {string} destPath The path to write the file to.
+ * @returns {Function} Returns the partially applied function.
+ */
+function min(srcPath, destPath) {
+  return _.partial(minify, srcPath, destPath);
+}
+
+/**
+ * Creates a [fs.writeFile](https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback)
+ * function with `filePath` and `data` partially applied.
+ *
+ * @memberOf file
+ * @param {string} destPath The path to write the file to.
+ * @param {string} data The data to write to the file.
+ * @returns {Function} Returns the partially applied function.
+ */
+function write(destPath, data) {
+  return _.partial(fs.writeFile, destPath, data);
+}
+
+/*----------------------------------------------------------------------------*/
+
+module.exports = {
+  'copy': copy,
+  'globTemplate': globTemplate,
+  'min': min,
+  'write': write
+};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/mapping.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/mapping.js
new file mode 100644
index 0000000..332f5af
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/mapping.js
@@ -0,0 +1,9 @@
+'use strict';
+
+var _mapping = require('../../fp/_mapping'),
+    util = require('./util'),
+    Hash = util.Hash;
+
+/*----------------------------------------------------------------------------*/
+
+module.exports = new Hash(_mapping);
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/minify.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/minify.js
new file mode 100644
index 0000000..7a0082d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/minify.js
@@ -0,0 +1,39 @@
+'use strict';
+
+var _ = require('lodash'),
+    fs = require('fs-extra'),
+    uglify = require('uglify-js');
+
+var uglifyOptions = require('./uglify.options');
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Asynchronously minifies the file at `srcPath`, writes it to `destPath`, and
+ * invokes `callback` upon completion. The callback is invoked with one argument:
+ * (error).
+ *
+ * If unspecified, `destPath` is `srcPath` with an extension of `.min.js`. For
+ * example, a `srcPath` of `path/to/foo.js` would have a `destPath` of `path/to/foo.min.js`.
+ *
+ * @param {string} srcPath The path of the file to minify.
+ * @param {string} [destPath] The path to write the file to.
+ * @param {Function} callback The function invoked upon completion.
+ * @param {Object} [option] The UglifyJS options object.
+ */
+function minify(srcPath, destPath, callback, options) {
+  if (_.isFunction(destPath)) {
+    if (_.isObject(callback)) {
+      options = callback;
+    }
+    callback = destPath;
+    destPath = undefined;
+  }
+  if (!destPath) {
+    destPath = srcPath.replace(/(?=\.js$)/, '.min');
+  }
+  var output = uglify.minify(srcPath, _.defaults(options || {}, uglifyOptions));
+  fs.writeFile(destPath, output.code, 'utf-8', callback);
+}
+
+module.exports = minify;
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/uglify.options.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/uglify.options.js
new file mode 100644
index 0000000..af0ff43
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/uglify.options.js
@@ -0,0 +1,23 @@
+'use strict';
+
+/**
+ * The UglifyJS options object for
+ * [compress](https://github.com/mishoo/UglifyJS2#compressor-options),
+ * [mangle](https://github.com/mishoo/UglifyJS2#mangler-options), and
+ * [output](https://github.com/mishoo/UglifyJS2#beautifier-options) options.
+ */
+module.exports = {
+  'compress': {
+    'pure_getters': true,
+    'unsafe': true,
+    'warnings': false
+  },
+  'mangle': {
+    'except': ['define']
+  },
+  'output': {
+    'ascii_only': true,
+    'comments': /^!|@cc_on|@license|@preserve/i,
+    'max_line_len': 500
+  }
+};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/util.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/util.js
new file mode 100644
index 0000000..6445186
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/common/util.js
@@ -0,0 +1,27 @@
+'use strict';
+
+var _ = require('lodash');
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Creates a hash object. If a `properties` object is provided, its own
+ * enumerable properties are assigned to the created object.
+ *
+ * @memberOf util
+ * @param {Object} [properties] The properties to assign to the object.
+ * @returns {Object} Returns the new hash object.
+ */
+function Hash(properties) {
+  return _.transform(properties, function(result, value, key) {
+    result[key] = (_.isPlainObject(value) && !(value instanceof Hash))
+      ? new Hash(value)
+      : value;
+  }, this);
+}
+
+Hash.prototype = Object.create(null);
+
+module.exports = {
+  'Hash': Hash
+};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-dist.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-dist.js
new file mode 100644
index 0000000..bad62d2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-dist.js
@@ -0,0 +1,55 @@
+'use strict';
+
+var _ = require('lodash'),
+    async = require('async'),
+    path = require('path'),
+    webpack = require('webpack');
+
+var file = require('../common/file');
+
+var basePath = path.join(__dirname, '..', '..'),
+    distPath = path.join(basePath, 'dist'),
+    fpPath = path.join(basePath, 'fp'),
+    filename = 'lodash.fp.js';
+
+var fpConfig = {
+  'entry': path.join(fpPath, '_convertBrowser.js'),
+  'output': {
+    'path': distPath,
+    'filename': filename,
+    'library': 'fp',
+    'libraryTarget': 'umd'
+  },
+  'plugins': [
+    new webpack.optimize.OccurenceOrderPlugin,
+    new webpack.optimize.DedupePlugin
+  ]
+};
+
+var mappingConfig = {
+  'entry': path.join(fpPath, '_mapping.js'),
+  'output': {
+    'path': distPath,
+    'filename': 'mapping.fp.js',
+    'library': 'mapping',
+    'libraryTarget': 'umd'
+  }
+};
+
+/*----------------------------------------------------------------------------*/
+
+function onComplete(error) {
+  if (error) {
+    throw error;
+  }
+}
+
+function build() {
+  async.series([
+    _.partial(webpack, mappingConfig),
+    _.partial(webpack, fpConfig),
+    file.min(path.join(distPath, filename))
+  ], onComplete);
+}
+
+build();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-doc.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-doc.js
new file mode 100644
index 0000000..02800bc
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-doc.js
@@ -0,0 +1,65 @@
+'use strict';
+
+var _ = require('lodash'),
+    fs = require('fs-extra'),
+    path = require('path');
+
+var file = require('../common/file'),
+    mapping = require('../common/mapping');
+
+var templatePath = path.join(__dirname, 'template/doc'),
+    template = file.globTemplate(path.join(templatePath, '*.jst'));
+
+var argNames = ['a', 'b', 'c', 'd'];
+
+var templateData = {
+  'mapping': mapping,
+  'toArgOrder': toArgOrder,
+  'toFuncList': toFuncList
+};
+
+function toArgOrder(array) {
+  var reordered = [];
+  _.each(array, function(newIndex, index) {
+    reordered[newIndex] = argNames[index];
+  });
+  return '`(' + reordered.join(', ') + ')`';
+}
+
+function toFuncList(array) {
+  var chunks = _.chunk(array.slice().sort(), 5),
+      lastChunk = _.last(chunks),
+      last = lastChunk ? lastChunk.pop() : undefined;
+
+  chunks = _.reject(chunks, _.isEmpty);
+  lastChunk = _.last(chunks);
+
+  var result = '`' + _.map(chunks, function(chunk) {
+    return chunk.join('`, `') + '`';
+  }).join(',\n`');
+
+  if (last == null) {
+    return result;
+  }
+  if (_.size(chunks) > 1 || _.size(lastChunk) > 1) {
+    result += ',';
+  }
+  result += ' &';
+  result += _.size(lastChunk) < 5 ? ' ' : '\n';
+  return result + '`' + last + '`';
+}
+
+/*----------------------------------------------------------------------------*/
+
+function onComplete(error) {
+  if (error) {
+    throw error;
+  }
+}
+
+function build(target) {
+  target = path.resolve(target);
+  fs.writeFile(target, template.wiki(templateData), onComplete);
+}
+
+build(_.last(process.argv));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-modules.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-modules.js
new file mode 100644
index 0000000..43902e0
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/build-modules.js
@@ -0,0 +1,120 @@
+'use strict';
+
+var _ = require('lodash'),
+    async = require('async'),
+    glob = require('glob'),
+    path = require('path');
+
+var file = require('../common/file'),
+    mapping = require('../common/mapping');
+
+var templatePath = path.join(__dirname, 'template/modules'),
+    template = file.globTemplate(path.join(templatePath, '*.jst'));
+
+var aryMethods = _.union(
+  mapping.aryMethod[1],
+  mapping.aryMethod[2],
+  mapping.aryMethod[3],
+  mapping.aryMethod[4]
+);
+
+var categories = [
+  'array',
+  'collection',
+  'date',
+  'function',
+  'lang',
+  'math',
+  'number',
+  'object',
+  'seq',
+  'string',
+  'util'
+];
+
+var ignored = [
+  '_*.js',
+  'core.js',
+  'core.min.js',
+  'fp.js',
+  'index.js',
+  'lodash.js',
+  'lodash.min.js'
+];
+
+function isAlias(funcName) {
+  return _.has(mapping.aliasToReal, funcName);
+}
+
+function isCategory(funcName) {
+  return _.includes(categories, funcName);
+}
+
+function isThru(funcName) {
+  return !_.includes(aryMethods, funcName);
+}
+
+function getTemplate(moduleName) {
+  var data = {
+    'name': _.result(mapping.aliasToReal, moduleName, moduleName),
+    'mapping': mapping
+  };
+
+  if (isAlias(moduleName)) {
+    return template.alias(data);
+  }
+  if (isCategory(moduleName)) {
+    return template.category(data);
+  }
+  if (isThru(moduleName)) {
+    return template.thru(data);
+  }
+  return template.module(data);
+}
+
+/*----------------------------------------------------------------------------*/
+
+function onComplete(error) {
+  if (error) {
+    throw error;
+  }
+}
+
+function build(target) {
+  target = path.resolve(target);
+
+  var fpPath = path.join(target, 'fp');
+
+  // Glob existing lodash module paths.
+  var modulePaths = glob.sync(path.join(target, '*.js'), {
+    'nodir': true,
+    'ignore': ignored.map(function(filename) {
+      return path.join(target, filename);
+    })
+  });
+
+  // Add FP alias and remapped module paths.
+  _.each([mapping.aliasToReal, mapping.remap], function(data) {
+    _.forOwn(data, function(realName, alias) {
+      var modulePath = path.join(target, alias + '.js');
+      if (!_.includes(modulePaths, modulePath)) {
+        modulePaths.push(modulePath);
+      }
+    });
+  });
+
+  var actions = modulePaths.map(function(modulePath) {
+    var moduleName = path.basename(modulePath, '.js');
+    return file.write(path.join(fpPath, moduleName + '.js'), getTemplate(moduleName));
+  });
+
+  actions.unshift(file.copy(path.join(__dirname, '../../fp'), fpPath));
+  actions.push(file.write(path.join(fpPath, '_falseOptions.js'), template._falseOptions()));
+  actions.push(file.write(path.join(fpPath, '_util.js'), template._util()));
+  actions.push(file.write(path.join(target, 'fp.js'), template.fp()));
+  actions.push(file.write(path.join(fpPath, 'convert.js'), template.convert()));
+
+  async.series(actions, onComplete);
+}
+
+build(_.last(process.argv));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/doc/wiki.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/doc/wiki.jst
new file mode 100644
index 0000000..188302f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/doc/wiki.jst
@@ -0,0 +1,220 @@
+## lodash/fp
+
+The `lodash/fp` module is an instance of `lodash` with its methods wrapped to
+produce immutable auto-curried iteratee-first data-last methods.
+
+## Installation
+
+In a browser:
+```html
+<script src='path/to/lodash.js'></script>
+<script src='path/to/lodash.fp.js'></script>
+<script>
+// Loading `lodash.fp.js` converts `_` to its fp variant.
+_.defaults({ 'a': 2, 'b': 2 })({ 'a': 1 });
+// → { 'a: 1, 'b': 2 }
+
+// Use `noConflict` to restore the pre-fp variant.
+var fp = _.noConflict();
+
+_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 });
+// → { 'a: 1, 'b': 2 }
+fp.defaults({ 'a': 2, 'b': 2 })({ 'a': 1 });
+// → { 'a: 1, 'b': 2 }
+</script>
+```
+
+In Node.js:
+```js
+// Load the fp build.
+var fp = require('lodash/fp');
+
+// Load a method category.
+var object = require('lodash/fp/object');
+
+// Load a single method for smaller builds with browserify/rollup/webpack.
+var extend = require('lodash/fp/extend');
+```
+
+## Mapping
+
+Immutable auto-curried iteratee-first data-last methods sound great, but what
+does that really mean for each method? Below is a breakdown of the mapping used
+to convert each method.
+
+#### Capped Iteratee Arguments
+
+Iteratee arguments are capped to avoid gotchas with variadic iteratees.
+```js
+// The `lodash/map` iteratee receives three arguments:
+// (value, index|key, collection)
+_.map(['6', '8', '10'], parseInt);
+// → [6, NaN, 2]
+
+// The `lodash/fp/map` iteratee is capped at one argument:
+// (value)
+fp.map(parseInt)(['6', '8', '10']);
+// → [6, 8, 10]
+```
+
+Methods that cap iteratees to one argument:<br>
+<%= toFuncList(_.keys(_.pickBy(mapping.iterateeAry, _.partial(_.eq, _, 1)))) %>
+
+Methods that cap iteratees to two arguments:<br>
+<%= toFuncList(_.keys(_.pickBy(mapping.iterateeAry, _.partial(_.eq, _, 2)))) %>
+
+The iteratee of `mapKeys` is invoked with one argument: (key)
+
+#### Fixed Arity
+
+Methods have fixed arities to support auto-currying.
+```js
+// `lodash/padStart` accepts an optional `chars` param.
+_.padStart('a', 3, '-')
+// → '--a'
+
+// `lodash/fp/padStart` does not.
+fp.padStart(3)('a');
+// → '  a'
+fp.padCharsStart('-')(3)('a');
+// → '--a'
+```
+
+Methods with a fixed arity of one:<br>
+<%= toFuncList(_.difference(mapping.aryMethod[1], _.keys(mapping.skipFixed))) %>
+
+Methods with a fixed arity of two:<br>
+<%= toFuncList(_.difference(mapping.aryMethod[2], _.keys(mapping.skipFixed))) %>
+
+Methods with a fixed arity of three:<br>
+<%= toFuncList(_.difference(mapping.aryMethod[3], _.keys(mapping.skipFixed))) %>
+
+Methods with a fixed arity of four:<br>
+<%= toFuncList(_.difference(mapping.aryMethod[4], _.keys(mapping.skipFixed))) %>
+
+#### Rearranged Arguments
+
+Method arguments are rearranged to make composition easier.
+```js
+// `lodash/filter` is data-first iteratee-last:
+// (collection, iteratee)
+var compact = _.partial(_.filter, _, Boolean);
+compact(['a', null, 'c']);
+// → ['a', 'c']
+
+// `lodash/fp/filter` is iteratee-first data-last:
+// (iteratee, collection)
+var compact = fp.filter(Boolean);
+compact(['a', null, 'c']);
+// → ['a', 'c']
+```
+
+##### Most methods follow these rules
+
+A fixed arity of two has an argument order of:<br>
+<%= toArgOrder(mapping.aryRearg[2]) %>
+
+A fixed arity of three has an argument order of:<br>
+<%= toArgOrder(mapping.aryRearg[3]) %>
+
+A fixed arity of four has an argument order of:<br>
+<%= toArgOrder(mapping.aryRearg[4]) %>
+
+##### Exceptions to the rules
+
+Methods that accept an array of arguments as their second parameter:<br>
+<%= toFuncList(_.keys(mapping.methodSpread)) %>
+
+Methods with unchanged argument orders:<br>
+<%= toFuncList(_.keys(mapping.skipRearg)) %>
+
+Methods with custom argument orders:<br>
+<%= _.map(_.keys(mapping.methodRearg), function(methodName) {
+  var orders = mapping.methodRearg[methodName];
+  return ' * `_.' + methodName + '` has an order of ' + toArgOrder(orders);
+}).join('\n') %>
+
+#### New Methods
+
+Not all variadic methods have corresponding new method variants. Feel free to
+[request](https://github.com/lodash/lodash/blob/master/.github/CONTRIBUTING.md#feature-requests)
+any additions.
+
+Methods created to accommodate Lodash’s variadic methods:<br>
+<%= toFuncList(_.keys(mapping.remap)) %>
+
+#### Aliases
+
+There are <%= _.size(mapping.aliasToReal) %> method aliases:<br>
+<%= _.map(_.keys(mapping.aliasToReal).sort(), function(alias) {
+  var realName = mapping.aliasToReal[alias];
+  return ' * `_.' + alias + '` is an alias of `_.' + realName + '`';
+}).join('\n') %>
+
+## Placeholders
+
+The placeholder argument, which defaults to `_`, may be used to fill in method
+arguments in a different order. Placeholders are filled by the first available
+arguments of the curried returned function.
+```js
+// The equivalent of `2 > 5`.
+_.gt(2)(5);
+// → false
+
+// The equivalent of `_.gt(5, 2)` or `5 > 2`.
+_.gt(_, 2)(5);
+// → true
+```
+
+## Chaining
+
+The `lodash/fp` module **does not** convert chain sequence methods. See
+[Izaak Schroeder’s article](https://medium.com/making-internets/why-using-chain-is-a-mistake-9bc1f80d51ba)
+on using functional composition as an alternative to method chaining.
+
+## Convert
+
+Although `lodash/fp` & its method modules come pre-converted, there are times
+when you may want to customize the conversion. That’s when the `convert` method
+comes in handy.
+```js
+// Every option is `true` by default.
+var _fp = fp.convert({
+  // Specify capping iteratee arguments.
+  'cap': true,
+  // Specify currying.
+  'curry': true,
+  // Specify fixed arity.
+  'fixed': true,
+  // Specify immutable operations.
+  'immutable': true,
+  // Specify rearranging arguments.
+  'rearg': true
+});
+
+// The `convert` method is available on each method too.
+var mapValuesWithKey = fp.mapValues.convert({ 'cap': false });
+
+// Here’s an example of disabling iteratee argument caps to access the `key` param.
+mapValuesWithKey(function(value, key) {
+  return key == 'a' ? -1 : value;
+})({ 'a': 1, 'b': 1 });
+// => { 'a': -1, 'b': 1 }
+```
+
+Manual conversions are also possible with the `convert` module.
+```js
+var convert = require('lodash/fp/convert');
+
+// Convert by name.
+var assign = convert('assign', require('lodash.assign'));
+
+// Convert by object.
+var fp = convert({
+  'assign': require('lodash.assign'),
+  'chunk': require('lodash.chunk')
+});
+
+// Convert by `lodash` instance.
+var fp = convert(lodash.runInContext());
+```
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/_falseOptions.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/_falseOptions.jst
new file mode 100644
index 0000000..773235e
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/_falseOptions.jst
@@ -0,0 +1,7 @@
+module.exports = {
+  'cap': false,
+  'curry': false,
+  'fixed': false,
+  'immutable': false,
+  'rearg': false
+};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/_util.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/_util.jst
new file mode 100644
index 0000000..d450396
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/_util.jst
@@ -0,0 +1,14 @@
+module.exports = {
+  'ary': require('../ary'),
+  'assign': require('../_baseAssign'),
+  'clone': require('../clone'),
+  'curry': require('../curry'),
+  'forEach': require('../_arrayEach'),
+  'isArray': require('../isArray'),
+  'isFunction': require('../isFunction'),
+  'iteratee': require('../iteratee'),
+  'keys': require('../_baseKeys'),
+  'rearg': require('../rearg'),
+  'spread': require('../spread'),
+  'toPath': require('../toPath')
+};
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/alias.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/alias.jst
new file mode 100644
index 0000000..6d72710
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/alias.jst
@@ -0,0 +1 @@
+module.exports = require('./<%= name %>');
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/category.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/category.jst
new file mode 100644
index 0000000..62c2db8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/category.jst
@@ -0,0 +1,2 @@
+var convert = require('./convert');
+module.exports = convert(require('../<%= name %>'));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/convert.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/convert.jst
new file mode 100644
index 0000000..4795dc4
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/convert.jst
@@ -0,0 +1,18 @@
+var baseConvert = require('./_baseConvert'),
+    util = require('./_util');
+
+/**
+ * Converts `func` of `name` to an immutable auto-curried iteratee-first data-last
+ * version with conversion `options` applied. If `name` is an object its methods
+ * will be converted.
+ *
+ * @param {string} name The name of the function to wrap.
+ * @param {Function} [func] The function to wrap.
+ * @param {Object} [options] The options object. See `baseConvert` for more details.
+ * @returns {Function|Object} Returns the converted function or object.
+ */
+function convert(name, func, options) {
+  return baseConvert(util, name, func, options);
+}
+
+module.exports = convert;
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/fp.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/fp.jst
new file mode 100644
index 0000000..e372dbb
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/fp.jst
@@ -0,0 +1,2 @@
+var _ = require('./lodash.min').runInContext();
+module.exports = require('./fp/_baseConvert')(_, _);
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/module.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/module.jst
new file mode 100644
index 0000000..289bd2b
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/module.jst
@@ -0,0 +1,5 @@
+var convert = require('./convert'),
+    func = convert('<%= name %>', require('../<%= _.result(mapping.remap, name, name) %>'));
+
+func.placeholder = require('./placeholder');
+module.exports = func;
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/thru.jst b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/thru.jst
new file mode 100644
index 0000000..5bc1a7b
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/fp/template/modules/thru.jst
@@ -0,0 +1,5 @@
+var convert = require('./convert'),
+    func = convert('<%= name %>', require('../<%= _.result(mapping.remap, name, name) %>'), require('./_falseOptions'));
+
+func.placeholder = require('./placeholder');
+module.exports = func;
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-dist.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-dist.js
new file mode 100644
index 0000000..14b3fd3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-dist.js
@@ -0,0 +1,30 @@
+'use strict';
+
+var async = require('async'),
+    path = require('path');
+
+var file = require('../common/file');
+
+var basePath = path.join(__dirname, '..', '..'),
+    distPath = path.join(basePath, 'dist'),
+    filename = 'lodash.js';
+
+var baseLodash = path.join(basePath, filename),
+    distLodash = path.join(distPath, filename);
+
+/*----------------------------------------------------------------------------*/
+
+function onComplete(error) {
+  if (error) {
+    throw error;
+  }
+}
+
+function build() {
+  async.series([
+    file.copy(baseLodash, distLodash),
+    file.min(distLodash)
+  ], onComplete);
+}
+
+build();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-doc.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-doc.js
new file mode 100644
index 0000000..9756954
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-doc.js
@@ -0,0 +1,60 @@
+'use strict';
+
+var _ = require('lodash'),
+    docdown = require('docdown'),
+    fs = require('fs-extra'),
+    path = require('path');
+
+var basePath = path.join(__dirname, '..', '..'),
+    docPath = path.join(basePath, 'doc'),
+    readmePath = path.join(docPath, 'README.md');
+
+var pkg = require('../../package.json'),
+    version = pkg.version;
+
+var config = {
+  'base': {
+    'entryLinks': [
+      '<% if (name == "templateSettings" || !/^(?:methods|properties|seq)$/i.test(category)) {' +
+      'print("[&#x24C3;](https://www.npmjs.com/package/lodash." + name.toLowerCase() + " \\"See the npm package\\")")' +
+      '} %>'
+    ],
+    'path': path.join(basePath, 'lodash.js'),
+    'title': '<a href="https://lodash.com/">lodash</a> <span>v' + version + '</span>',
+    'toc': 'categories',
+    'url': 'https://github.com/lodash/lodash/blob/' + version + '/lodash.js'
+  },
+  'github': {
+    'hash': 'github'
+  },
+  'site': {
+    'tocLink': '#docs'
+  }
+};
+
+function postprocess(string) {
+  // Fix docdown bugs.
+  return string
+    // Repair the default value of `chars`.
+    // See https://github.com/eslint/doctrine/issues/157 for more details.
+    .replace(/\bchars=''/g, "chars=' '")
+    // Wrap symbol property identifiers in brackets.
+    .replace(/\.(Symbol\.(?:[a-z]+[A-Z]?)+)/g, '[$1]');
+}
+
+/*----------------------------------------------------------------------------*/
+
+function onComplete(error) {
+  if (error) {
+    throw error;
+  }
+}
+
+function build(type) {
+  var options = _.defaults({}, config.base, config[type]),
+      markdown = docdown(options);
+
+  fs.writeFile(readmePath, postprocess(markdown), onComplete);
+}
+
+build(_.last(process.argv));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-modules.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-modules.js
new file mode 100644
index 0000000..5d89e0d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lib/main/build-modules.js
@@ -0,0 +1,34 @@
+'use strict';
+
+var _ = require('lodash'),
+    async = require('async'),
+    path = require('path');
+
+var file = require('../common/file');
+
+var basePath = path.join(__dirname, '..', '..'),
+    distPath = path.join(basePath, 'dist');
+
+var filePairs = [
+  [path.join(distPath, 'lodash.core.js'), 'core.js'],
+  [path.join(distPath, 'lodash.core.min.js'), 'core.min.js'],
+  [path.join(distPath, 'lodash.min.js'), 'lodash.min.js']
+];
+
+/*----------------------------------------------------------------------------*/
+
+function onComplete(error) {
+  if (error) {
+    throw error;
+  }
+}
+
+function build(target) {
+  var actions = _.map(filePairs, function(pair) {
+    return file.copy(pair[0], path.join(target, pair[1]));
+  });
+
+  async.series(actions, onComplete);
+}
+
+build(_.last(process.argv));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/lodash.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/lodash.js
new file mode 100644
index 0000000..9f472f6
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/lodash.js
@@ -0,0 +1,16148 @@
+/**
+ * @license
+ * lodash 4.11.2 <https://lodash.com/>
+ * Copyright jQuery Foundation and other contributors <https://jquery.org/>
+ * 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.11.2';
+
+  /** Used as the size to enable large array optimizations. */
+  var LARGE_ARRAY_SIZE = 200;
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT = 'Expected a function';
+
+  /** Used to stand-in for `undefined` hash values. */
+  var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+  /** Used as the internal argument placeholder. */
+  var PLACEHOLDER = '__lodash_placeholder__';
+
+  /** Used to compose bitmasks for wrapper metadata. */
+  var BIND_FLAG = 1,
+      BIND_KEY_FLAG = 2,
+      CURRY_BOUND_FLAG = 4,
+      CURRY_FLAG = 8,
+      CURRY_RIGHT_FLAG = 16,
+      PARTIAL_FLAG = 32,
+      PARTIAL_RIGHT_FLAG = 64,
+      ARY_FLAG = 128,
+      REARG_FLAG = 256,
+      FLIP_FLAG = 512;
+
+  /** Used to compose bitmasks for comparison styles. */
+  var UNORDERED_COMPARE_FLAG = 1,
+      PARTIAL_COMPARE_FLAG = 2;
+
+  /** 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 = 150,
+      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;
+
+  /** `Object#toString` result references. */
+  var argsTag = '[object Arguments]',
+      arrayTag = '[object Array]',
+      boolTag = '[object Boolean]',
+      dateTag = '[object Date]',
+      errorTag = '[object Error]',
+      funcTag = '[object Function]',
+      genTag = '[object GeneratorFunction]',
+      mapTag = '[object Map]',
+      numberTag = '[object Number]',
+      objectTag = '[object Object]',
+      promiseTag = '[object Promise]',
+      regexpTag = '[object RegExp]',
+      setTag = '[object Set]',
+      stringTag = '[object String]',
+      symbolTag = '[object Symbol]',
+      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|#96);/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*$/,
+      rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
+
+  /**
+   * Used to match `RegExp`
+   * [syntax characters](http://ecma-international.org/ecma-262/6.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 non-compound words composed of alphanumeric characters. */
+  var reBasicWord = /[a-zA-Z0-9]+/g;
+
+  /** Used to match backslashes in property paths. */
+  var reEscapeChar = /\\(\\)?/g;
+
+  /**
+   * Used to match
+   * [ES template delimiters](http://ecma-international.org/ecma-262/6.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 hexadecimal string values. */
+  var reHasHexPrefix = /^0x/i;
+
+  /** 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-1 supplementary letters (excluding mathematical operators). */
+  var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/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\\ufe20-\\ufe23',
+      rsComboSymbolsRange = '\\u20d0-\\u20f0',
+      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 = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
+      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 rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
+      rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
+      rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?',
+      rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?',
+      reOptMod = rsModifier + '?',
+      rsOptVar = '[' + rsVarRange + ']?',
+      rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+      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 reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g');
+
+  /** Used to match complex or compound words. */
+  var reComplexWord = RegExp([
+    rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+    rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
+    rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr,
+    rsUpper + '+' + rsOptUpperContr,
+    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 reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange  + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']');
+
+  /** Used to detect strings that need a more robust regexp to match words. */
+  var reHasComplexWord = /[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', 'Reflect', '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-1 supplementary letters to basic latin letters. */
+  var deburredLetters = {
+    '\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'
+  };
+
+  /** Used to map characters to HTML entities. */
+  var htmlEscapes = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;',
+    '`': '&#96;'
+  };
+
+  /** Used to map HTML entities to characters. */
+  var htmlUnescapes = {
+    '&amp;': '&',
+    '&lt;': '<',
+    '&gt;': '>',
+    '&quot;': '"',
+    '&#39;': "'",
+    '&#96;': '`'
+  };
+
+  /** Used to determine if values are of the language type `Object`. */
+  var objectTypes = {
+    'function': true,
+    'object': true
+  };
+
+  /** 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 `exports`. */
+  var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+    ? exports
+    : undefined;
+
+  /** Detect free variable `module`. */
+  var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+    ? module
+    : undefined;
+
+  /** Detect the popular CommonJS extension `module.exports`. */
+  var moduleExports = (freeModule && freeModule.exports === freeExports)
+    ? freeExports
+    : undefined;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+  /** Detect free variable `self`. */
+  var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+  /** Detect free variable `window`. */
+  var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+  /** Detect `this` as the global object. */
+  var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+  /**
+   * Used as a reference to the global object.
+   *
+   * The `this` value is used if it's the global object to avoid Greasemonkey's
+   * restricted `window` object, otherwise the `window` object is used.
+   */
+  var root = freeGlobal ||
+    ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+      freeSelf || thisGlobal || Function('return this')();
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * 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 doesn't return the map instance 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) {
+    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) {
+    var length = args.length;
+    switch (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.length;
+
+    while (++index < length) {
+      var value = array[index];
+      setter(accumulator, value, iteratee(value), array);
+    }
+    return accumulator;
+  }
+
+  /**
+   * Creates a new array concatenating `array` with `other`.
+   *
+   * @private
+   * @param {Array} array The first array to concatenate.
+   * @param {Array} other The second array to concatenate.
+   * @returns {Array} Returns the new concatenated array.
+   */
+  function arrayConcat(array, other) {
+    var index = -1,
+        length = array.length,
+        othIndex = -1,
+        othLength = other.length,
+        result = Array(length + othLength);
+
+    while (++index < length) {
+      result[index] = array[index];
+    }
+    while (++othIndex < othLength) {
+      result[index++] = other[othIndex];
+    }
+    return result;
+  }
+
+  /**
+   * 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.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.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.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.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 search.
+   * @param {*} target The value to search for.
+   * @returns {boolean} Returns `true` if `target` is found, else `false`.
+   */
+  function arrayIncludes(array, value) {
+    return !!array.length && baseIndexOf(array, value, 0) > -1;
+  }
+
+  /**
+   * This function is like `arrayIncludes` except that it accepts a comparator.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @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.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.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.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.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.length;
+
+    while (++index < length) {
+      if (predicate(array[index], index, array)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * The base implementation of methods like `_.find` and `_.findKey`, without
+   * support for iteratee shorthands, which iterates over `collection` using
+   * `eachFunc`.
+   *
+   * @private
+   * @param {Array|Object} collection The collection to search.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {Function} eachFunc The function to iterate over `collection`.
+   * @param {boolean} [retKey] Specify returning the key of the found element
+   *  instead of the element itself.
+   * @returns {*} Returns the found element or its key, else `undefined`.
+   */
+  function baseFind(collection, predicate, eachFunc, retKey) {
+    var result;
+    eachFunc(collection, function(value, key, collection) {
+      if (predicate(value, key, collection)) {
+        result = retKey ? key : value;
+        return false;
+      }
+    });
+    return result;
+  }
+
+  /**
+   * The base implementation of `_.findIndex` and `_.findLastIndex` without
+   * support for iteratee shorthands.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @param {Function} predicate The function invoked per iteration.
+   * @param {boolean} [fromRight] Specify iterating from right to left.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function baseFindIndex(array, predicate, fromRight) {
+    var length = array.length,
+        index = fromRight ? length : -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 search.
+   * @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) {
+    if (value !== value) {
+      return indexOfNaN(array, fromIndex);
+    }
+    var index = fromIndex - 1,
+        length = array.length;
+
+    while (++index < length) {
+      if (array[index] === value) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * This function is like `baseIndexOf` except that it accepts a comparator.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @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 `_.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 ? array.length : 0;
+    return length ? (baseSum(array, iteratee) / length) : NAN;
+  }
+
+  /**
+   * 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 new array of 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 wrapper metadata.
+   *
+   * @private
+   * @param {Function} func The function to cap arguments for.
+   * @returns {Function} Returns the new 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];
+    });
+  }
+
+  /**
+   * 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;
+  }
+
+  /**
+   * Checks if `value` is a global object.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+   */
+  function checkGlobal(value) {
+    return (value && value.Object === Object) ? value : null;
+  }
+
+  /**
+   * 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 supplementary letters to basic latin letters.
+   *
+   * @private
+   * @param {string} letter The matched letter to deburr.
+   * @returns {string} Returns the deburred letter.
+   */
+  function deburrLetter(letter) {
+    return deburredLetters[letter];
+  }
+
+  /**
+   * Used by `_.escape` to convert characters to HTML entities.
+   *
+   * @private
+   * @param {string} chr The matched character to escape.
+   * @returns {string} Returns the escaped character.
+   */
+  function escapeHtmlChar(chr) {
+    return htmlEscapes[chr];
+  }
+
+  /**
+   * 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 index at which the first occurrence of `NaN` is found in `array`.
+   *
+   * @private
+   * @param {Array} array The array to search.
+   * @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 `NaN`, else `-1`.
+   */
+  function indexOfNaN(array, fromIndex, fromRight) {
+    var length = array.length,
+        index = fromIndex + (fromRight ? 0 : -1);
+
+    while ((fromRight ? index-- : ++index < length)) {
+      var other = array[index];
+      if (other !== other) {
+        return index;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Checks if `value` is a host object in IE < 9.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+   */
+  function isHostObject(value) {
+    // Many host objects are `Object` objects that can coerce to strings
+    // despite having improperly defined `toString` methods.
+    var result = false;
+    if (value != null && typeof value.toString != 'function') {
+      try {
+        result = !!(value + '');
+      } catch (e) {}
+    }
+    return result;
+  }
+
+  /**
+   * 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 an array.
+   *
+   * @private
+   * @param {Object} map The map to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function mapToArray(map) {
+    var index = -1,
+        result = Array(map.size);
+
+    map.forEach(function(value, key) {
+      result[++index] = [key, value];
+    });
+    return result;
+  }
+
+  /**
+   * 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.
+   *
+   * @private
+   * @param {Object} set The set to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function setToArray(set) {
+    var index = -1,
+        result = Array(set.size);
+
+    set.forEach(function(value) {
+      result[++index] = value;
+    });
+    return result;
+  }
+
+  /**
+   * Gets the number of symbols in `string`.
+   *
+   * @private
+   * @param {string} string The string to inspect.
+   * @returns {number} Returns the string size.
+   */
+  function stringSize(string) {
+    if (!(string && reHasComplexSymbol.test(string))) {
+      return string.length;
+    }
+    var result = reComplexSymbol.lastIndex = 0;
+    while (reComplexSymbol.test(string)) {
+      result++;
+    }
+    return result;
+  }
+
+  /**
+   * Converts `string` to an array.
+   *
+   * @private
+   * @param {string} string The string to convert.
+   * @returns {Array} Returns the converted array.
+   */
+  function stringToArray(string) {
+    return string.match(reComplexSymbol);
+  }
+
+  /**
+   * Used by `_.unescape` to convert HTML entities to characters.
+   *
+   * @private
+   * @param {string} chr The matched character to unescape.
+   * @returns {string} Returns the unescaped character.
+   */
+  function unescapeHtmlChar(chr) {
+    return htmlUnescapes[chr];
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * 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
+   *
+   * // Use `context` to mock `Date#getTime` use in `_.now`.
+   * var mock = _.runInContext({
+   *   'Date': function() {
+   *     return { 'getTime': getTimeMock };
+   *   }
+   * });
+   *
+   * // Create a suped-up `defer` in Node.js.
+   * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer;
+   */
+  function runInContext(context) {
+    context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root;
+
+    /** Built-in constructor references. */
+    var Date = context.Date,
+        Error = context.Error,
+        Math = context.Math,
+        RegExp = context.RegExp,
+        TypeError = context.TypeError;
+
+    /** Used for built-in method references. */
+    var arrayProto = context.Array.prototype,
+        objectProto = context.Object.prototype,
+        stringProto = context.String.prototype;
+
+    /** Used to resolve the decompiled source of functions. */
+    var funcToString = context.Function.prototype.toString;
+
+    /** Used to check objects for own properties. */
+    var hasOwnProperty = objectProto.hasOwnProperty;
+
+    /** Used to generate unique IDs. */
+    var idCounter = 0;
+
+    /** Used to infer the `Object` constructor. */
+    var objectCtorString = funcToString.call(Object);
+
+    /**
+     * Used to resolve the
+     * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+     * of values.
+     */
+    var objectToString = objectProto.toString;
+
+    /** 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,
+        Reflect = context.Reflect,
+        Symbol = context.Symbol,
+        Uint8Array = context.Uint8Array,
+        clearTimeout = context.clearTimeout,
+        enumerate = Reflect ? Reflect.enumerate : undefined,
+        getOwnPropertySymbols = Object.getOwnPropertySymbols,
+        iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined,
+        objectCreate = Object.create,
+        propertyIsEnumerable = objectProto.propertyIsEnumerable,
+        setTimeout = context.setTimeout,
+        splice = arrayProto.splice;
+
+    /* Built-in method references for those with the same name as other `lodash` methods. */
+    var nativeCeil = Math.ceil,
+        nativeFloor = Math.floor,
+        nativeGetPrototype = Object.getPrototypeOf,
+        nativeIsFinite = context.isFinite,
+        nativeJoin = arrayProto.join,
+        nativeKeys = Object.keys,
+        nativeMax = Math.max,
+        nativeMin = Math.min,
+        nativeParseInt = context.parseInt,
+        nativeRandom = Math.random,
+        nativeReplace = stringProto.replace,
+        nativeReverse = arrayProto.reverse,
+        nativeSplit = stringProto.split;
+
+    /* 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;
+
+    /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
+    var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
+
+    /** 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 of at least `200` elements
+     * and any 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`, `deburr`, `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`, `subtract`, `sum`, `sumBy`, `template`, `times`, `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 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). 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 || arrLength < LARGE_ARRAY_SIZE ||
+          (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
+     * @returns {Object} Returns the new hash object.
+     */
+    function Hash() {}
+
+    /**
+     * Removes `key` and its value from the hash.
+     *
+     * @private
+     * @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(hash, key) {
+      return hashHas(hash, key) && delete hash[key];
+    }
+
+    /**
+     * Gets the hash value for `key`.
+     *
+     * @private
+     * @param {Object} hash The hash to query.
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function hashGet(hash, key) {
+      if (nativeCreate) {
+        var result = hash[key];
+        return result === HASH_UNDEFINED ? undefined : result;
+      }
+      return hasOwnProperty.call(hash, key) ? hash[key] : undefined;
+    }
+
+    /**
+     * Checks if a hash value for `key` exists.
+     *
+     * @private
+     * @param {Object} hash The hash 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 hashHas(hash, key) {
+      return nativeCreate ? hash[key] !== undefined : hasOwnProperty.call(hash, key);
+    }
+
+    /**
+     * Sets the hash `key` to `value`.
+     *
+     * @private
+     * @param {Object} hash The hash to modify.
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     */
+    function hashSet(hash, key, value) {
+      hash[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+    }
+
+    // Avoid inheriting from `Object.prototype` when possible.
+    Hash.prototype = nativeCreate ? nativeCreate(null) : objectProto;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a map cache object to store key-value pairs.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function MapCache(values) {
+      var index = -1,
+          length = values ? values.length : 0;
+
+      this.clear();
+      while (++index < length) {
+        var entry = values[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the map.
+     *
+     * @private
+     * @name clear
+     * @memberOf MapCache
+     */
+    function mapClear() {
+      this.__data__ = {
+        'hash': new Hash,
+        'map': Map ? new Map : [],
+        '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 mapDelete(key) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        return hashDelete(typeof key == 'string' ? data.string : data.hash, key);
+      }
+      return Map ? data.map['delete'](key) : assocDelete(data.map, key);
+    }
+
+    /**
+     * 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 mapGet(key) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        return hashGet(typeof key == 'string' ? data.string : data.hash, key);
+      }
+      return Map ? data.map.get(key) : assocGet(data.map, 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 mapHas(key) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        return hashHas(typeof key == 'string' ? data.string : data.hash, key);
+      }
+      return Map ? data.map.has(key) : assocHas(data.map, 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 mapSet(key, value) {
+      var data = this.__data__;
+      if (isKeyable(key)) {
+        hashSet(typeof key == 'string' ? data.string : data.hash, key, value);
+      } else if (Map) {
+        data.map.set(key, value);
+      } else {
+        assocSet(data.map, key, value);
+      }
+      return this;
+    }
+
+    // Add methods to `MapCache`.
+    MapCache.prototype.clear = mapClear;
+    MapCache.prototype['delete'] = mapDelete;
+    MapCache.prototype.get = mapGet;
+    MapCache.prototype.has = mapHas;
+    MapCache.prototype.set = mapSet;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     *
+     * Creates a set cache object to store unique values.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function SetCache(values) {
+      var index = -1,
+          length = values ? values.length : 0;
+
+      this.__data__ = new MapCache;
+      while (++index < length) {
+        this.push(values[index]);
+      }
+    }
+
+    /**
+     * Checks if `value` is in `cache`.
+     *
+     * @private
+     * @param {Object} cache The set cache to search.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns `true` if `value` is found, else `false`.
+     */
+    function cacheHas(cache, value) {
+      var map = cache.__data__;
+      if (isKeyable(value)) {
+        var data = map.__data__,
+            hash = typeof value == 'string' ? data.string : data.hash;
+
+        return hash[value] === HASH_UNDEFINED;
+      }
+      return map.has(value);
+    }
+
+    /**
+     * Adds `value` to the set cache.
+     *
+     * @private
+     * @name push
+     * @memberOf SetCache
+     * @param {*} value The value to cache.
+     */
+    function cachePush(value) {
+      var map = this.__data__;
+      if (isKeyable(value)) {
+        var data = map.__data__,
+            hash = typeof value == 'string' ? data.string : data.hash;
+
+        hash[value] = HASH_UNDEFINED;
+      }
+      else {
+        map.set(value, HASH_UNDEFINED);
+      }
+    }
+
+    // Add methods to `SetCache`.
+    SetCache.prototype.push = cachePush;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Creates a stack cache object to store key-value pairs.
+     *
+     * @private
+     * @constructor
+     * @param {Array} [values] The values to cache.
+     */
+    function Stack(values) {
+      var index = -1,
+          length = values ? values.length : 0;
+
+      this.clear();
+      while (++index < length) {
+        var entry = values[index];
+        this.set(entry[0], entry[1]);
+      }
+    }
+
+    /**
+     * Removes all key-value entries from the stack.
+     *
+     * @private
+     * @name clear
+     * @memberOf Stack
+     */
+    function stackClear() {
+      this.__data__ = { 'array': [], 'map': null };
+    }
+
+    /**
+     * 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__,
+          array = data.array;
+
+      return array ? assocDelete(array, key) : data.map['delete'](key);
+    }
+
+    /**
+     * 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) {
+      var data = this.__data__,
+          array = data.array;
+
+      return array ? assocGet(array, key) : data.map.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) {
+      var data = this.__data__,
+          array = data.array;
+
+      return array ? assocHas(array, key) : data.map.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__,
+          array = data.array;
+
+      if (array) {
+        if (array.length < (LARGE_ARRAY_SIZE - 1)) {
+          assocSet(array, key, value);
+        } else {
+          data.array = null;
+          data.map = new MapCache(array);
+        }
+      }
+      var map = data.map;
+      if (map) {
+        map.set(key, value);
+      }
+      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;
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Removes `key` and its value from the associative array.
+     *
+     * @private
+     * @param {Array} array The array to modify.
+     * @param {string} key The key of the value to remove.
+     * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+     */
+    function assocDelete(array, key) {
+      var index = assocIndexOf(array, key);
+      if (index < 0) {
+        return false;
+      }
+      var lastIndex = array.length - 1;
+      if (index == lastIndex) {
+        array.pop();
+      } else {
+        splice.call(array, index, 1);
+      }
+      return true;
+    }
+
+    /**
+     * Gets the associative array value for `key`.
+     *
+     * @private
+     * @param {Array} array The array to query.
+     * @param {string} key The key of the value to get.
+     * @returns {*} Returns the entry value.
+     */
+    function assocGet(array, key) {
+      var index = assocIndexOf(array, key);
+      return index < 0 ? undefined : array[index][1];
+    }
+
+    /**
+     * Checks if an associative array value for `key` exists.
+     *
+     * @private
+     * @param {Array} array The array 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 assocHas(array, key) {
+      return assocIndexOf(array, key) > -1;
+    }
+
+    /**
+     * Gets the index at which the `key` is found in `array` of key-value pairs.
+     *
+     * @private
+     * @param {Array} array The array to search.
+     * @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;
+    }
+
+    /**
+     * Sets the associative array `key` to `value`.
+     *
+     * @private
+     * @param {Array} array The array to modify.
+     * @param {string} key The key of the value to set.
+     * @param {*} value The value to set.
+     */
+    function assocSet(array, key, value) {
+      var index = assocIndexOf(array, key);
+      if (index < 0) {
+        array.push([key, value]);
+      } else {
+        array[index][1] = value;
+      }
+    }
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * Used by `_.defaults` to customize its `_.assignIn` use.
+     *
+     * @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 assignInDefaults(objValue, srcValue, key, object) {
+      if (objValue === undefined ||
+          (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
+        return srcValue;
+      }
+      return objValue;
+    }
+
+    /**
+     * 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)) ||
+          (typeof key == 'number' && value === undefined && !(key in object))) {
+        object[key] = value;
+      }
+    }
+
+    /**
+     * Assigns `value` to `key` of `object` if the existing value is not equivalent
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.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))) {
+        object[key] = value;
+      }
+    }
+
+    /**
+     * 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 `_.at` without support for individual paths.
+     *
+     * @private
+     * @param {Object} object The object to iterate over.
+     * @param {string[]} paths The property paths of elements to pick.
+     * @returns {Array} Returns the new array of picked elements.
+     */
+    function baseAt(object, paths) {
+      var index = -1,
+          isNil = object == null,
+          length = paths.length,
+          result = Array(length);
+
+      while (++index < length) {
+        result[index] = isNil ? undefined : get(object, paths[index]);
+      }
+      return result;
+    }
+
+    /**
+     * The base implementation of `_.clamp` which doesn't coerce arguments to numbers.
+     *
+     * @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} [isDeep] Specify a deep clone.
+     * @param {boolean} [isFull] Specify a clone including 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, isDeep, isFull, customizer, key, object, stack) {
+      var result;
+      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)) {
+          if (isHostObject(value)) {
+            return object ? value : {};
+          }
+          result = initCloneObject(isFunc ? {} : value);
+          if (!isDeep) {
+            return 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);
+
+      if (!isArr) {
+        var props = isFull ? getAllKeys(value) : keys(value);
+      }
+      // Recursively populate clone (susceptible to call stack limits).
+      arrayEach(props || value, function(subValue, key) {
+        if (props) {
+          key = subValue;
+          subValue = value[key];
+        }
+        assignValue(result, key, baseClone(subValue, isDeep, isFull, 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 function.
+     */
+    function baseConforms(source) {
+      var props = keys(source),
+          length = props.length;
+
+      return function(object) {
+        if (object == null) {
+          return !length;
+        }
+        var index = length;
+        while (index--) {
+          var key = props[index],
+              predicate = source[key],
+              value = object[key];
+
+          if ((value === undefined &&
+              !(key in Object(object))) || !predicate(value)) {
+            return false;
+          }
+        }
+        return true;
+      };
+    }
+
+    /**
+     * The base implementation of `_.create` without support for assigning
+     * properties to the created object.
+     *
+     * @private
+     * @param {Object} prototype The object to inherit from.
+     * @returns {Object} Returns the new object.
+     */
+    function baseCreate(proto) {
+      return isObject(proto) ? objectCreate(proto) : {};
+    }
+
+    /**
+     * The base implementation of `_.delay` and `_.defer` which accepts an array
+     * of `func` arguments.
+     *
+     * @private
+     * @param {Function} func The function to delay.
+     * @param {number} wait The number of milliseconds to delay invocation.
+     * @param {Object} args The arguments to provide to `func`.
+     * @returns {number} Returns the timer id.
+     */
+    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 ? iteratee(value) : 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 new array of filtered property 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 = isKey(path, object) ? [path] : castPath(path);
+
+      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 `_.gt` which doesn't coerce arguments to numbers.
+     *
+     * @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) {
+      // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
+      // that are composed entirely of index properties, return `false` for
+      // `hasOwnProperty` checks of them.
+      return hasOwnProperty.call(object, key) ||
+        (typeof object == 'object' && key in object && getPrototype(object) === null);
+    }
+
+    /**
+     * 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 key in Object(object);
+    }
+
+    /**
+     * The base implementation of `_.inRange` which doesn't coerce arguments to numbers.
+     *
+     * @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) {
+      if (!isKey(path, object)) {
+        path = castPath(path);
+        object = parent(object, path);
+        path = last(path);
+      }
+      var func = object == null ? object : object[toKey(path)];
+      return func == null ? undefined : apply(func, object, args);
+    }
+
+    /**
+     * 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 {Function} [customizer] The function to customize comparisons.
+     * @param {boolean} [bitmask] The bitmask of comparison flags.
+     *  The bitmask may be composed of the following flags:
+     *     1 - Unordered comparison
+     *     2 - Partial comparison
+     * @param {Object} [stack] Tracks traversed `value` and `other` objects.
+     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+     */
+    function baseIsEqual(value, other, customizer, bitmask, stack) {
+      if (value === other) {
+        return true;
+      }
+      if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) {
+        return value !== value && other !== other;
+      }
+      return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, 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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} [customizer] The function to customize comparisons.
+     * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @param {Object} [stack] Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) {
+      var objIsArr = isArray(object),
+          othIsArr = isArray(other),
+          objTag = arrayTag,
+          othTag = arrayTag;
+
+      if (!objIsArr) {
+        objTag = getTag(object);
+        objTag = objTag == argsTag ? objectTag : objTag;
+      }
+      if (!othIsArr) {
+        othTag = getTag(other);
+        othTag = othTag == argsTag ? objectTag : othTag;
+      }
+      var objIsObj = objTag == objectTag && !isHostObject(object),
+          othIsObj = othTag == objectTag && !isHostObject(other),
+          isSameTag = objTag == othTag;
+
+      if (isSameTag && !objIsObj) {
+        stack || (stack = new Stack);
+        return (objIsArr || isTypedArray(object))
+          ? equalArrays(object, other, equalFunc, customizer, bitmask, stack)
+          : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack);
+      }
+      if (!(bitmask & PARTIAL_COMPARE_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, customizer, bitmask, stack);
+        }
+      }
+      if (!isSameTag) {
+        return false;
+      }
+      stack || (stack = new Stack);
+      return equalObjects(object, other, equalFunc, customizer, bitmask, stack);
+    }
+
+    /**
+     * 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, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack)
+                : result
+              )) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+
+    /**
+     * 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 skip the constructor
+     * property of prototypes or treat sparse arrays as dense.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function baseKeys(object) {
+      return nativeKeys(Object(object));
+    }
+
+    /**
+     * The base implementation of `_.keysIn` which doesn't skip the constructor
+     * property of prototypes or treat sparse arrays as dense.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of property names.
+     */
+    function baseKeysIn(object) {
+      object = object == null ? object : Object(object);
+
+      var result = [];
+      for (var key in object) {
+        result.push(key);
+      }
+      return result;
+    }
+
+    // Fallback for IE < 9 with es6-shim.
+    if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
+      baseKeysIn = function(object) {
+        return iteratorToArray(enumerate(object));
+      };
+    }
+
+    /**
+     * The base implementation of `_.lt` which doesn't coerce arguments to numbers.
+     *
+     * @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 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 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, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_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;
+      }
+      if (!(isArray(source) || isTypedArray(source))) {
+        var props = keysIn(source);
+      }
+      arrayEach(props || source, function(srcValue, key) {
+        if (props) {
+          key = srcValue;
+          srcValue = source[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);
+        }
+      });
+    }
+
+    /**
+     * 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) {
+        newValue = srcValue;
+        if (isArray(srcValue) || isTypedArray(srcValue)) {
+          if (isArray(objValue)) {
+            newValue = objValue;
+          }
+          else if (isArrayLikeObject(objValue)) {
+            newValue = copyArray(objValue);
+          }
+          else {
+            isCommon = false;
+            newValue = baseClone(srcValue, true);
+          }
+        }
+        else if (isPlainObject(srcValue) || isArguments(srcValue)) {
+          if (isArguments(objValue)) {
+            newValue = toPlainObject(objValue);
+          }
+          else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) {
+            isCommon = false;
+            newValue = baseClone(srcValue, true);
+          }
+          else {
+            newValue = objValue;
+          }
+        }
+        else {
+          isCommon = false;
+        }
+      }
+      stack.set(srcValue, newValue);
+
+      if (isCommon) {
+        // Recursively merge objects and arrays (susceptible to call stack limits).
+        mergeFunc(newValue, srcValue, srcIndex, customizer, stack);
+      }
+      stack['delete'](srcValue);
+      assignMergeValue(object, key, newValue);
+    }
+
+    /**
+     * The base implementation of `_.nth` which doesn't coerce `n` to an integer.
+     *
+     * @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[]} props The property identifiers to pick.
+     * @returns {Object} Returns the new object.
+     */
+    function basePick(object, props) {
+      object = Object(object);
+      return arrayReduce(props, function(result, key) {
+        if (key in object) {
+          result[key] = object[key];
+        }
+        return result;
+      }, {});
+    }
+
+    /**
+     * The base implementation of  `_.pickBy` without support for iteratee shorthands.
+     *
+     * @private
+     * @param {Object} object The source object.
+     * @param {Function} predicate The function invoked per property.
+     * @returns {Object} Returns the new object.
+     */
+    function basePickBy(object, predicate) {
+      var index = -1,
+          props = getAllKeysIn(object),
+          length = props.length,
+          result = {};
+
+      while (++index < length) {
+        var key = props[index],
+            value = object[key];
+
+        if (predicate(value, key)) {
+          result[key] = value;
+        }
+      }
+      return result;
+    }
+
+    /**
+     * 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 function.
+     */
+    function baseProperty(key) {
+      return function(object) {
+        return object == null ? undefined : object[key];
+      };
+    }
+
+    /**
+     * 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 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 (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 if (!isKey(index, array)) {
+            var path = castPath(index),
+                object = parent(array, path);
+
+            if (object != null) {
+              delete object[toKey(last(path))];
+            }
+          }
+          else {
+            delete array[toKey(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 to numbers.
+     *
+     * @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 new array 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 `_.set`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @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) {
+      path = isKey(path, object) ? [path] : castPath(path);
+
+      var index = -1,
+          length = path.length,
+          lastIndex = length - 1,
+          nested = object;
+
+      while (nested != null && ++index < length) {
+        var key = toKey(path[index]);
+        if (isObject(nested)) {
+          var newValue = value;
+          if (index != lastIndex) {
+            var objValue = nested[key];
+            newValue = customizer ? customizer(objValue, key, nested) : undefined;
+            if (newValue === undefined) {
+              newValue = objValue == null
+                ? (isIndex(path[index + 1]) ? [] : {})
+                : objValue;
+            }
+          }
+          assignValue(nested, key, newValue);
+        }
+        nested = nested[key];
+      }
+      return object;
+    }
+
+    /**
+     * The base implementation of `setData` without support for hot loop detection.
+     *
+     * @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 `_.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 ? array.length : low;
+
+      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 ? array.length : 0,
+          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 (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 path of the property to unset.
+     * @returns {boolean} Returns `true` if the property is deleted, else `false`.
+     */
+    function baseUnset(object, path) {
+      path = isKey(path, object) ? [path] : castPath(path);
+      object = parent(object, path);
+
+      var key = toKey(last(path));
+      return !(object != null && baseHas(object, key)) || delete object[key];
+    }
+
+    /**
+     * The base implementation of `_.update`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @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 index = -1,
+          length = arrays.length;
+
+      while (++index < length) {
+        var result = result
+          ? arrayPush(
+              baseDifference(result, arrays[index], iteratee, comparator),
+              baseDifference(arrays[index], result, iteratee, comparator)
+            )
+          : arrays[index];
+      }
+      return (result && result.length) ? baseUniq(result, 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.
+     * @returns {Array} Returns the cast property path array.
+     */
+    function castPath(value) {
+      return isArray(value) ? value : stringToPath(value);
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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 result = new buffer.constructor(buffer.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), true) : 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), true) : 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|Object} 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|Object} 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) {
+      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)
+          : source[key];
+
+        assignValue(object, key, newValue);
+      }
+      return object;
+    }
+
+    /**
+     * Copies own symbol properties 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);
+    }
+
+    /**
+     * 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), 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 rest(function(object, sources) {
+        var index = -1,
+            length = sources.length,
+            customizer = length > 1 ? sources[length - 1] : undefined,
+            guard = length > 2 ? sources[2] : undefined;
+
+        customizer = 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 of wrapper flags. See `createWrapper`
+     *  for more details.
+     * @param {*} [thisArg] The `this` binding of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createBaseWrapper(func, bitmask, thisArg) {
+      var isBind = bitmask & BIND_FLAG,
+          Ctor = createCtorWrapper(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 function.
+     */
+    function createCaseFirst(methodName) {
+      return function(string) {
+        string = toString(string);
+
+        var strSymbols = reHasComplexSymbol.test(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 createCtorWrapper(Ctor) {
+      return function() {
+        // Use a `switch` statement to work with class constructors. See
+        // http://ecma-international.org/ecma-262/6.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 of wrapper flags. See `createWrapper`
+     *  for more details.
+     * @param {number} arity The arity of `func`.
+     * @returns {Function} Returns the new wrapped function.
+     */
+    function createCurryWrapper(func, bitmask, arity) {
+      var Ctor = createCtorWrapper(func);
+
+      function wrapper() {
+        var length = arguments.length,
+            args = Array(length),
+            index = length,
+            placeholder = getPlaceholder(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 createRecurryWrapper(
+            func, bitmask, createHybridWrapper, 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 `_.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 rest(function(funcs) {
+        funcs = baseFlatten(funcs, 1);
+
+        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] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | 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) && value.length >= LARGE_ARRAY_SIZE) {
+            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 of wrapper flags. See `createWrapper`
+     *  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 createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
+      var isAry = bitmask & ARY_FLAG,
+          isBind = bitmask & BIND_FLAG,
+          isBindKey = bitmask & BIND_KEY_FLAG,
+          isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG),
+          isFlip = bitmask & FLIP_FLAG,
+          Ctor = isBindKey ? undefined : createCtorWrapper(func);
+
+      function wrapper() {
+        var length = arguments.length,
+            index = length,
+            args = Array(length);
+
+        while (index--) {
+          args[index] = arguments[index];
+        }
+        if (isCurried) {
+          var placeholder = getPlaceholder(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 createRecurryWrapper(
+            func, bitmask, createHybridWrapper, 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 || createCtorWrapper(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.
+     * @returns {Function} Returns the new mathematical operation function.
+     */
+    function createMathOperation(operator) {
+      return function(value, other) {
+        var result;
+        if (value === undefined && other === undefined) {
+          return 0;
+        }
+        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 invoker function.
+     */
+    function createOver(arrayFunc) {
+      return rest(function(iteratees) {
+        iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
+          ? arrayMap(iteratees[0], baseUnary(getIteratee()))
+          : arrayMap(baseFlatten(iteratees, 1, isFlattenableIteratee), baseUnary(getIteratee()));
+
+        return rest(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 reHasComplexSymbol.test(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 of wrapper flags. See `createWrapper`
+     *  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 createPartialWrapper(func, bitmask, thisArg, partials) {
+      var isBind = bitmask & BIND_FLAG,
+          Ctor = createCtorWrapper(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 = toNumber(start);
+        start = start === start ? start : 0;
+        if (end === undefined) {
+          end = start;
+          start = 0;
+        } else {
+          end = toNumber(end) || 0;
+        }
+        step = step === undefined ? (start < end ? 1 : -1) : (toNumber(step) || 0);
+        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 of wrapper flags. See `createWrapper`
+     *  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 createRecurryWrapper(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
+      var isCurry = bitmask & CURRY_FLAG,
+          newHolders = isCurry ? holders : undefined,
+          newHoldersRight = isCurry ? undefined : holders,
+          newPartials = isCurry ? partials : undefined,
+          newPartialsRight = isCurry ? undefined : partials;
+
+      bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG);
+      bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG);
+
+      if (!(bitmask & CURRY_BOUND_FLAG)) {
+        bitmask &= ~(BIND_FLAG | 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 result;
+    }
+
+    /**
+     * 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 = toInteger(precision);
+        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 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 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 of wrapper flags.
+     *  The bitmask may be composed of the following 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`
+     * @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 createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
+      var isBindKey = bitmask & BIND_KEY_FLAG;
+      if (!isBindKey && typeof func != 'function') {
+        throw new TypeError(FUNC_ERROR_TEXT);
+      }
+      var length = partials ? partials.length : 0;
+      if (!length) {
+        bitmask &= ~(PARTIAL_FLAG | 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 & 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] == null
+        ? (isBindKey ? 0 : func.length)
+        : nativeMax(newData[9] - length, 0);
+
+      if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) {
+        bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG);
+      }
+      if (!bitmask || bitmask == BIND_FLAG) {
+        var result = createBaseWrapper(func, bitmask, thisArg);
+      } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) {
+        result = createCurryWrapper(func, bitmask, arity);
+      } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) {
+        result = createPartialWrapper(func, bitmask, thisArg, partials);
+      } else {
+        result = createHybridWrapper.apply(undefined, newData);
+      }
+      var setter = data ? baseSetData : setData;
+      return setter(result, newData);
+    }
+
+    /**
+     * 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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @param {Object} stack Tracks traversed `array` and `other` objects.
+     * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
+     */
+    function equalArrays(array, other, equalFunc, customizer, bitmask, stack) {
+      var index = -1,
+          isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+          isUnordered = bitmask & UNORDERED_COMPARE_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) {
+        return stacked == other;
+      }
+      var result = true;
+      stack.set(array, other);
+
+      // 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 (isUnordered) {
+          if (!arraySome(other, function(othValue) {
+                return arrValue === othValue ||
+                  equalFunc(arrValue, othValue, customizer, bitmask, stack);
+              })) {
+            result = false;
+            break;
+          }
+        } else if (!(
+              arrValue === othValue ||
+                equalFunc(arrValue, othValue, customizer, bitmask, stack)
+            )) {
+          result = false;
+          break;
+        }
+      }
+      stack['delete'](array);
+      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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @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, equalFunc, customizer, bitmask, 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:
+          // Coerce dates and booleans to numbers, dates to milliseconds and
+          // booleans to `1` or `0` treating invalid dates coerced to `NaN` as
+          // not equal.
+          return +object == +other;
+
+        case errorTag:
+          return object.name == other.name && object.message == other.message;
+
+        case numberTag:
+          // Treat `NaN` vs. `NaN` as equal.
+          return (object != +object) ? other != +other : object == +other;
+
+        case regexpTag:
+        case stringTag:
+          // Coerce regexes to strings and treat strings, primitives and objects,
+          // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring
+          // for more details.
+          return object == (other + '');
+
+        case mapTag:
+          var convert = mapToArray;
+
+        case setTag:
+          var isPartial = bitmask & PARTIAL_COMPARE_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 |= UNORDERED_COMPARE_FLAG;
+          stack.set(object, other);
+
+          // Recursively compare objects (susceptible to call stack limits).
+          return equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack);
+
+        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 {Function} equalFunc The function to determine equivalents of values.
+     * @param {Function} customizer The function to customize comparisons.
+     * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual`
+     *  for more details.
+     * @param {Object} stack Tracks traversed `object` and `other` objects.
+     * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
+     */
+    function equalObjects(object, other, equalFunc, customizer, bitmask, stack) {
+      var isPartial = bitmask & PARTIAL_COMPARE_FLAG,
+          objProps = keys(object),
+          objLength = objProps.length,
+          othProps = keys(other),
+          othLength = othProps.length;
+
+      if (objLength != othLength && !isPartial) {
+        return false;
+      }
+      var index = objLength;
+      while (index--) {
+        var key = objProps[index];
+        if (!(isPartial ? key in other : baseHas(other, key))) {
+          return false;
+        }
+      }
+      // Assume cyclic values are equal.
+      var stacked = stack.get(object);
+      if (stacked) {
+        return stacked == other;
+      }
+      var result = true;
+      stack.set(object, other);
+
+      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, customizer, bitmask, 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);
+      return result;
+    }
+
+    /**
+     * 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 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 "length" property value of `object`.
+     *
+     * **Note:** This function is used to avoid a
+     * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
+     * Safari on at least iOS 8.1-8.3 ARM64.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {*} Returns the "length" value.
+     */
+    var getLength = baseProperty('length');
+
+    /**
+     * 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 = toPairs(object),
+          length = result.length;
+
+      while (length--) {
+        result[length][2] = isStrictComparable(result[length][1]);
+      }
+      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 = object[key];
+      return isNative(value) ? value : undefined;
+    }
+
+    /**
+     * Gets the argument placeholder value for `func`.
+     *
+     * @private
+     * @param {Function} func The function to inspect.
+     * @returns {*} Returns the placeholder value.
+     */
+    function getPlaceholder(func) {
+      var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func;
+      return object.placeholder;
+    }
+
+    /**
+     * Gets the `[[Prototype]]` of `value`.
+     *
+     * @private
+     * @param {*} value The value to query.
+     * @returns {null|Object} Returns the `[[Prototype]]`.
+     */
+    function getPrototype(value) {
+      return nativeGetPrototype(Object(value));
+    }
+
+    /**
+     * Creates an array of the own enumerable symbol properties of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of symbols.
+     */
+    function getSymbols(object) {
+      // Coerce `object` to an object to avoid non-object errors in V8.
+      // See https://bugs.chromium.org/p/v8/issues/detail?id=3443 for more details.
+      return getOwnPropertySymbols(Object(object));
+    }
+
+    // Fallback for IE < 11.
+    if (!getOwnPropertySymbols) {
+      getSymbols = function() {
+        return [];
+      };
+    }
+
+    /**
+     * Creates an array of the own and inherited enumerable symbol properties
+     * of `object`.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the array of symbols.
+     */
+    var getSymbolsIn = !getOwnPropertySymbols ? getSymbols : 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`.
+     */
+    function getTag(value) {
+      return objectToString.call(value);
+    }
+
+    // Fallback for data views, maps, sets, and weak maps in IE 11,
+    // for data views in Edge, and promises in Node.js.
+    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 = objectToString.call(value),
+            Ctor = result == objectTag ? value.constructor : undefined,
+            ctorString = Ctor ? toSource(Ctor) : undefined;
+
+        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 };
+    }
+
+    /**
+     * 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 = isKey(path, object) ? [path] : castPath(path);
+
+      var result,
+          index = -1,
+          length = path.length;
+
+      while (++index < length) {
+        var key = toKey(path[index]);
+        if (!(result = object != null && hasFunc(object, key))) {
+          break;
+        }
+        object = object[key];
+      }
+      if (result) {
+        return result;
+      }
+      var length = object ? object.length : 0;
+      return !!length && isLength(length) && isIndex(key, length) &&
+        (isArray(object) || isString(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);
+      }
+    }
+
+    /**
+     * Creates an array of index keys for `object` values of arrays,
+     * `arguments` objects, and strings, otherwise `null` is returned.
+     *
+     * @private
+     * @param {Object} object The object to query.
+     * @returns {Array|null} Returns index keys, else `null`.
+     */
+    function indexKeys(object) {
+      var length = object ? object.length : undefined;
+      if (isLength(length) &&
+          (isArray(object) || isString(object) || isArguments(object))) {
+        return baseTimes(length, String);
+      }
+      return null;
+    }
+
+    /**
+     * 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 isArrayLikeObject(value) && (isArray(value) || isArguments(value));
+    }
+
+    /**
+     * Checks if `value` is a flattenable array and not a `_.matchesProperty`
+     * iteratee shorthand.
+     *
+     * @private
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
+     */
+    function isFlattenableIteratee(value) {
+      return isArray(value) && !(value.length == 2 && !isFunction(value[0]));
+    }
+
+    /**
+     * 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 `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 function.
+     */
+    function matchesStrictComparable(key, srcValue) {
+      return function(object) {
+        if (object == null) {
+          return false;
+        }
+        return object[key] === srcValue &&
+          (srcValue !== undefined || (key in Object(object)));
+      };
+    }
+
+    /**
+     * 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 < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG);
+
+      var isCombo =
+        ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) ||
+        ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) ||
+        ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG));
+
+      // Exit early if metadata can't be merged.
+      if (!(isCommon || isCombo)) {
+        return data;
+      }
+      // Use source `thisArg` if available.
+      if (srcBitmask & BIND_FLAG) {
+        data[2] = source[2];
+        // Set when currying a bound function.
+        newBitmask |= bitmask & BIND_FLAG ? 0 : 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 & 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;
+    }
+
+    /**
+     * Used by `_.defaultsDeep` to customize its `_.merge` use.
+     *
+     * @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 mergeDefaults(objValue, srcValue, key, object, source, stack) {
+      if (isObject(objValue) && isObject(srcValue)) {
+        baseMerge(objValue, srcValue, undefined, mergeDefaults, stack.set(srcValue, objValue));
+      }
+      return objValue;
+    }
+
+    /**
+     * 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 == 1 ? 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 = (function() {
+      var count = 0,
+          lastCalled = 0;
+
+      return function(key, value) {
+        var stamp = now(),
+            remaining = HOT_SPAN - (stamp - lastCalled);
+
+        lastCalled = stamp;
+        if (remaining > 0) {
+          if (++count >= HOT_COUNT) {
+            return key;
+          }
+        } else {
+          count = 0;
+        }
+        return baseSetData(key, value);
+      };
+    }());
+
+    /**
+     * Converts `string` to a property path array.
+     *
+     * @private
+     * @param {string} string The string to convert.
+     * @returns {Array} Returns the property path array.
+     */
+    var stringToPath = memoize(function(string) {
+      var result = [];
+      toString(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 process.
+     * @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 '';
+    }
+
+    /**
+     * 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 containing 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 ? array.length : 0;
+      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 ? array.length : 0,
+          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,
+          array = castArray(arguments[0]);
+
+      if (length < 2) {
+        return length ? copyArray(array) : [];
+      }
+      var args = Array(length - 1);
+      while (length--) {
+        args[length - 1] = arguments[length];
+      }
+      return arrayConcat(array, baseFlatten(args, 1));
+    }
+
+    /**
+     * Creates an array of unique `array` values not included in the other given
+     * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+     * for equality comparisons. The order of result values is determined by the
+     * order they occur in the first 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([3, 2, 1], [4, 2]);
+     * // => [3, 1]
+     */
+    var difference = rest(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. Result values are chosen from the first 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 {...Array} [values] The values to exclude.
+     * @param {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of filtered values.
+     * @example
+     *
+     * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
+     * // => [3.1, 1.3]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+     * // => [{ 'x': 2 }]
+     */
+    var differenceBy = rest(function(array, values) {
+      var iteratee = last(values);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return isArrayLikeObject(array)
+        ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee))
+        : [];
+    });
+
+    /**
+     * This method is like `_.difference` except that it accepts `comparator`
+     * which is invoked to compare elements of `array` to `values`. Result values
+     * are chosen from the first 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 {...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 = rest(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 ? array.length : 0;
+      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 ? array.length : 0;
+      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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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 ? array.length : 0;
+      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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @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) {
+      return (array && array.length)
+        ? baseFindIndex(array, getIteratee(predicate, 3))
+        : -1;
+    }
+
+    /**
+     * 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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @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) {
+      return (array && array.length)
+        ? baseFindIndex(array, getIteratee(predicate, 3), true)
+        : -1;
+    }
+
+    /**
+     * 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 ? array.length : 0;
+      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 ? array.length : 0;
+      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 ? array.length : 0;
+      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([['fred', 30], ['barney', 40]]);
+     * // => { 'fred': 30, 'barney': 40 }
+     */
+    function fromPairs(pairs) {
+      var index = -1,
+          length = pairs ? pairs.length : 0,
+          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/6.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 search.
+     * @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 ? array.length : 0;
+      if (!length) {
+        return -1;
+      }
+      fromIndex = toInteger(fromIndex);
+      if (fromIndex < 0) {
+        fromIndex = nativeMax(length + fromIndex, 0);
+      }
+      return baseIndexOf(array, value, fromIndex);
+    }
+
+    /**
+     * 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) {
+      return dropRight(array, 1);
+    }
+
+    /**
+     * Creates an array of unique values that are included in all given arrays
+     * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
+     * for equality comparisons. The order of result values is determined by the
+     * order they occur in 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], [4, 2], [1, 2]);
+     * // => [2]
+     */
+    var intersection = rest(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. Result values are chosen from 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 {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of intersecting values.
+     * @example
+     *
+     * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+     * // => [2.1]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }]
+     */
+    var intersectionBy = rest(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))
+        : [];
+    });
+
+    /**
+     * This method is like `_.intersection` except that it accepts `comparator`
+     * which is invoked to compare elements of `arrays`. Result values are chosen
+     * from 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 = rest(function(arrays) {
+      var comparator = last(arrays),
+          mapped = arrayMap(arrays, castArrayLikeObject);
+
+      if (comparator === last(mapped)) {
+        comparator = undefined;
+      } else {
+        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 ? 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 ? array.length : 0;
+      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 search.
+     * @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 ? array.length : 0;
+      if (!length) {
+        return -1;
+      }
+      var index = length;
+      if (fromIndex !== undefined) {
+        index = toInteger(fromIndex);
+        index = (
+          index < 0
+            ? nativeMax(length + index, 0)
+            : nativeMin(index, length - 1)
+        ) + 1;
+      }
+      if (value !== value) {
+        return indexOfNaN(array, index, true);
+      }
+      while (index--) {
+        if (array[index] === value) {
+          return index;
+        }
+      }
+      return -1;
+    }
+
+    /**
+     * Gets the nth element 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/6.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 = [1, 2, 3, 1, 2, 3];
+     *
+     * _.pull(array, 2, 3);
+     * console.log(array);
+     * // => [1, 1]
+     */
+    var pull = rest(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 = [1, 2, 3, 1, 2, 3];
+     *
+     * _.pullAll(array, [2, 3]);
+     * console.log(array);
+     * // => [1, 1]
+     */
+    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 {Array|Function|Object|string} [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))
+        : 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 = [5, 10, 15, 20];
+     * var evens = _.pullAt(array, 1, 3);
+     *
+     * console.log(array);
+     * // => [5, 15]
+     *
+     * console.log(evens);
+     * // => [10, 20]
+     */
+    var pullAt = rest(function(array, indexes) {
+      indexes = baseFlatten(indexes, 1);
+
+      var length = array ? array.length : 0,
+          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 {Array|Function|Object|string} [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 ? nativeReverse.call(array) : 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 ? array.length : 0;
+      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
+     *
+     * _.sortedIndex([4, 5], 4);
+     * // => 0
+     */
+    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 {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * var dict = { 'thirty': 30, 'forty': 40, 'fifty': 50 };
+     *
+     * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict));
+     * // => 1
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+     * // => 0
+     */
+    function sortedIndexBy(array, value, iteratee) {
+      return baseSortedIndexBy(array, value, getIteratee(iteratee));
+    }
+
+    /**
+     * 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 search.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.sortedIndexOf([1, 1, 2, 2], 2);
+     * // => 2
+     */
+    function sortedIndexOf(array, value) {
+      var length = array ? array.length : 0;
+      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], 4);
+     * // => 1
+     */
+    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 {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {number} Returns the index at which `value` should be inserted
+     *  into `array`.
+     * @example
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x');
+     * // => 1
+     */
+    function sortedLastIndexBy(array, value, iteratee) {
+      return baseSortedIndexBy(array, value, getIteratee(iteratee), 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 search.
+     * @param {*} value The value to search for.
+     * @returns {number} Returns the index of the matched value, else `-1`.
+     * @example
+     *
+     * _.sortedLastIndexOf([1, 1, 2, 2], 2);
+     * // => 3
+     */
+    function sortedLastIndexOf(array, value) {
+      var length = array ? array.length : 0;
+      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))
+        : [];
+    }
+
+    /**
+     * 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) {
+      return drop(array, 1);
+    }
+
+    /**
+     * 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 ? array.length : 0;
+      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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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/6.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], [4, 2], [1, 2]);
+     * // => [2, 1, 4]
+     */
+    var union = rest(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. The iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of combined values.
+     * @example
+     *
+     * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+     * // => [2.1, 1.2, 4.3]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 1 }, { 'x': 2 }]
+     */
+    var unionBy = rest(function(arrays) {
+      var iteratee = last(arrays);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee));
+    });
+
+    /**
+     * This method is like `_.union` except that it accepts `comparator` which
+     * is invoked to compare elements of `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 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 = rest(function(arrays) {
+      var comparator = last(arrays);
+      if (isArrayLikeObject(comparator)) {
+        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/6.0/#sec-samevaluezero)
+     * for equality comparisons, in which only the first occurrence of each
+     * element is kept.
+     *
+     * @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 iteratee is invoked with one argument: (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {Array} array The array to inspect.
+     * @param {Array|Function|Object|string} [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))
+        : [];
+    }
+
+    /**
+     * This method is like `_.uniq` except that it accepts `comparator` which
+     * is invoked to compare elements of `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) {
+      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(['fred', 'barney'], [30, 40], [true, false]);
+     * // => [['fred', 30, true], ['barney', 40, false]]
+     *
+     * _.unzip(zipped);
+     * // => [['fred', 'barney'], [30, 40], [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/6.0/#sec-samevaluezero)
+     * for equality comparisons.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Array
+     * @param {Array} array The array to filter.
+     * @param {...*} [values] The values to exclude.
+     * @returns {Array} Returns the new array of filtered values.
+     * @see _.difference, _.xor
+     * @example
+     *
+     * _.without([1, 2, 1, 3], 1, 2);
+     * // => [3]
+     */
+    var without = rest(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 values.
+     * @see _.difference, _.without
+     * @example
+     *
+     * _.xor([2, 1], [4, 2]);
+     * // => [1, 4]
+     */
+    var xor = rest(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 iteratee is invoked with one argument:
+     * (value).
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Array
+     * @param {...Array} [arrays] The arrays to inspect.
+     * @param {Array|Function|Object|string} [iteratee=_.identity]
+     *  The iteratee invoked per element.
+     * @returns {Array} Returns the new array of values.
+     * @example
+     *
+     * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+     * // => [1.2, 4.3]
+     *
+     * // The `_.property` iteratee shorthand.
+     * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+     * // => [{ 'x': 2 }]
+     */
+    var xorBy = rest(function(arrays) {
+      var iteratee = last(arrays);
+      if (isArrayLikeObject(iteratee)) {
+        iteratee = undefined;
+      }
+      return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee));
+    });
+
+    /**
+     * This method is like `_.xor` except that it accepts `comparator` which is
+     * invoked to compare elements of `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 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 = rest(function(arrays) {
+      var comparator = last(arrays);
+      if (isArrayLikeObject(comparator)) {
+        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(['fred', 'barney'], [30, 40], [true, false]);
+     * // => [['fred', 30, true], ['barney', 40, false]]
+     */
+    var zip = rest(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 = rest(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 of elements 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]
+     *
+     * _(['a', 'b', 'c']).at(0, 2).value();
+     * // => ['a', 'c']
+     */
+    var wrapperAt = rest(function(paths) {
+      paths = baseFlatten(paths, 1);
+      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 {Array|Function|Object|string} [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 }
+     *
+     * _.countBy(['one', 'two', 'three'], 'length');
+     * // => { '3': 2, '5': 1 }
+     */
+    var countBy = createAggregator(function(result, value, key) {
+      hasOwnProperty.call(result, key) ? ++result[key] : (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).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Array|Function|Object|string} [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).
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @category Collection
+     * @param {Array|Object} collection The collection to iterate over.
+     * @param {Array|Function|Object|string} [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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @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'
+     */
+    function find(collection, predicate) {
+      predicate = getIteratee(predicate, 3);
+      if (isArray(collection)) {
+        var index = baseFindIndex(collection, predicate);
+        return index > -1 ? collection[index] : undefined;
+      }
+      return baseFind(collection, predicate, baseEach);
+    }
+
+    /**
+     * 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 search.
+     * @param {Array|Function|Object|string} [predicate=_.identity]
+     *  The function invoked per iteration.
+     * @returns {*} Returns the matched element, else `undefined`.
+     * @example
+     *
+     * _.findLast([1, 2, 3, 4], function(n) {
+     *   return n % 2 == 1;
+     * });
+     * // => 3
+     */
+    function findLast(collection, predicate) {
+      predicate = getIteratee(predicate, 3);
+      if (isArray(collection)) {
+        var index = baseFindIndex(collection, predicate, true);
+        return index > -1 ? collection[index] : undefined;
+      }
+      return baseFind(collection, predicate, baseEachRight);
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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
+     *
+     * _([1, 2]).forEach(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) {
+      return (typeof iteratee == 'function' && isArray(collection))
+        ? arrayEach(collection, iteratee)
+        : baseEach(collection, getIteratee(iteratee));
+    }
+
+    /**
+     * 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) {
+      return (typeof iteratee == 'function' && isArray(collection))
+        ? arrayEachRight(collection, iteratee)
+        : baseEachRight(collection, getIteratee(iteratee));
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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 {
+        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/6.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 search.
+     * @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({ 'user': 'fred', 'age': 40 }, 'fred');
+     * // => true
+     *
+     * _.includes('pebbles', 'eb');
+     * // => 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 `methodName` 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 = rest(function(collection, path, args) {
+      var index = -1,
+          isFunc = typeof path == 'function',
+          isProp = isKey(path),
+          result = isArrayLike(collection) ? Array(collection.length) : [];
+
+      baseEach(collection, function(value) {
+        var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined);
+        result[++index] = func ? apply(func, 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 {Array|Function|Object|string} [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) {
+      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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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 {Array|Function|Object|string} [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;
+      predicate = getIteratee(predicate, 3);
+      return func(collection, function(value, index, collection) {
+        return !predicate(value, index, collection);
+      });
+    }
+
+    /**
+     * 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 array = isArrayLike(collection) ? collection : values(collection),
+          length = array.length;
+
+      return length > 0 ? array[baseRandom(0, length - 1)] : undefined;
+    }
+
+    /**
+     * 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) {
+      var index = -1,
+          result = toArray(collection),
+          length = result.length,
+          lastIndex = length - 1;
+
+      if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
+        n = 1;
+      } else {
+        n = baseClamp(toInteger(n), 0, length);
+      }
+      while (++index < n) {
+        var rand = baseRandom(index, lastIndex),
+            value = result[rand];
+
+        result[rand] = result[index];
+        result[index] = value;
+      }
+      result.length = n;
+      return result;
+    }
+
+    /**
+     * 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) {
+      return sampleSize(collection, MAX_ARRAY_LENGTH);
+    }
+
+    /**
+     * 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} 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)) {
+        var result = collection.length;
+        return (result && isString(collection)) ? stringSize(collection) : result;
+      }
+      if (isObjectLike(collection)) {
+        var tag = getTag(collection);
+        if (tag == mapTag || tag == setTag) {
+          return collection.size;
+        }
+      }
+      return keys(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 {Array|Function|Object|string} [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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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]]
+     *
+     * _.sortBy(users, 'user', function(o) {
+     *   return Math.floor(o.age / 10);
+     * });
+     * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
+     */
+    var sortBy = rest(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]];
+      }
+      iteratees = (iteratees.length == 1 && isArray(iteratees[0]))
+        ? iteratees[0]
+        : baseFlatten(iteratees, 1, isFlattenableIteratee);
+
+      return baseOrderBy(collection, iteratees, []);
+    });
+
+    /*------------------------------------------------------------------------*/
+
+    /**
+     * 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
+     * @type {Function}
+     * @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 function to be invoked.
+     */
+    var now = 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 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 createWrapper(func, 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
+     *
+     * var greet = function(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 = rest(function(func, thisArg, partials) {
+      var bitmask = BIND_FLAG;
+      if (partials.length) {
+        var holders = replaceHolders(partials, getPlaceholder(bind));
+        bitmask |= PARTIAL_FLAG;
+      }
+      return createWrapper(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 = rest(function(object, key, partials) {
+      var bitmask = BIND_FLAG | BIND_KEY_FLAG;
+      if (partials.length) {
+        var holders = replaceHolders(partials, getPlaceholder(bindKey));
+        bitmask |= PARTIAL_FLAG;
+      }
+      return createWrapper(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 = createWrapper(func, 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 = createWrapper(func, 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 an options object 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.
+     *
+     * 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 = 0,
+          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 || (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) {
+        clearTimeout(timerId);
+        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);
+        }
+        lastCallTime = lastInvokeTime = 0;
+        lastArgs = 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.
+            clearTimeout(timerId);
+            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 or more milliseconds.
+     */
+    var defer = rest(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 = rest(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 function.
+     * @example
+     *
+     * var flipped = _.flip(function() {
+     *   return _.toArray(arguments);
+     * });
+     *
+     * flipped('a', 'b', 'c', 'd');
+     * // => ['d', 'c', 'b', 'a']
+     */
+    function flip(func) {
+      return createWrapper(func, 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/6.0/#sec-properties-of-the-map-prototype-object)
+     * method interface of `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 memoizing 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 && 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);
+        return result;
+      };
+      memoized.cache = new (memoize.Cache || MapCache);
+      return memoized;
+    }
+
+    // Assign cache to `_.memoize`.
+    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 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() {
+        return !predicate.apply(this, arguments);
+      };
+    }
+
+    /**
+     * 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();
+     * // `initialize` invokes `createApplication` once
+     */
+    function once(func) {
+      return before(2, func);
+    }
+
+    /**
+     * Creates a function that invokes `func` with arguments transformed by
+     * corresponding `transforms`.
+     *
+     * @static
+     * @since 4.0.0
+     * @memberOf _
+     * @category Function
+     * @param {Function} func The function to wrap.
+     * @param {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [transforms[_.identity]] The functions to transform.
+     * @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 = rest(function(func, transforms) {
+      transforms = (transforms.length == 1 && isArray(transforms[0]))
+        ? arrayMap(transforms[0], baseUnary(getIteratee()))
+        : arrayMap(baseFlatten(transforms, 1, isFlattenableIteratee), baseUnary(getIteratee()));
+
+      var funcsLength = transforms.length;
+      return rest(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
+     *
+     * var greet = function(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 = rest(function(func, partials) {
+      var holders = replaceHolders(partials, getPlaceholder(partial));
+      return createWrapper(func, 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
+     *
+     * var greet = function(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 = rest(function(func, partials) {
+      var holders = replaceHolders(partials, getPlaceholder(partialRight));
+      return createWrapper(func, 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 = rest(function(func, indexes) {
+      return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1));
+    });
+
+    /**
+     * 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 = nativeMax(start === undefined ? (func.length - 1) : toInteger(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];
+        }
+        switch (start) {
+          case 0: return func.call(this, array);
+          case 1: return func.call(this, args[0], array);
+          case 2: return func.call(this, args[0], args[1], array);
+        }
+        var otherArgs = Array(start + 1);
+        index = -1;
+        while (++index < start) {
+          otherArgs[index] = args[index];
+        }
+        otherArgs[start] = array;
+        return apply(func, this, otherArgs);
+      };
+    }
+
+    /**
+     * 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/6.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 === undefined ? 0 : nativeMax(toInteger(start), 0);
+      return rest(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 an options object 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.
+     *
+     * 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 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 the wrapper function as its
+     * first argument. Any additional arguments provided to the function are
+     * appended to those provided to the wrapper function. 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) {
+      wrapper = wrapper == null ? identity : wrapper;
+      return partial(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, false, true);
+    }
+
+    /**
+     * 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) {
+      return baseClone(value, false, true, 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, true, true);
+    }
+
+    /**
+     * 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) {
+      return baseClone(value, true, true, customizer);
+    }
+
+    /**
+     * Performs a
+     * [`SameValueZero`](http://ecma-international.org/ecma-262/6.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 = { 'user': 'fred' };
+     * var other = { 'user': 'fred' };
+     *
+     * _.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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isArguments(function() { return arguments; }());
+     * // => true
+     *
+     * _.isArguments([1, 2, 3]);
+     * // => false
+     */
+    function isArguments(value) {
+      // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+      return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+        (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+    }
+
+    /**
+     * Checks if `value` is classified as an `Array` object.
+     *
+     * @static
+     * @memberOf _
+     * @since 0.1.0
+     * @type {Function}
+     * @category Lang
+     * @param {*} value The value to check.
+     * @returns {boolean} Returns `true` if `value` is correctly classified,
+     *  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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isArrayBuffer(new ArrayBuffer(2));
+     * // => true
+     *
+     * _.isArrayBuffer(new Array(2));
+     * // => false
+     */
+    function isArrayBuffer(value) {
+      return isObjectLike(value) && objectToString.call(value) == arrayBufferTag;
+    }
+
+    /**
+     * 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(getLength(value)) && !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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isBoolean(false);
+     * // => true
+     *
+     * _.isBoolean(null);
+     * // => false
+     */
+    function isBoolean(value) {
+      return value === true || value === false ||
+        (isObjectLike(value) && objectToString.call(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 = !Buffer ? constant(false) : function(value) {
+      return value instanceof Buffer;
+    };
+
+    /**
+     * 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isDate(new Date);
+     * // => true
+     *
+     * _.isDate('Mon April 23 2012');
+     * // => false
+     */
+    function isDate(value) {
+      return isObjectLike(value) && objectToString.call(value) == dateTag;
+    }
+
+    /**
+     * 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 !!value && value.nodeType === 1 && isObjectLike(value) && !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 (isArrayLike(value) &&
+          (isArray(value) || isString(value) || isFunction(value.splice) ||
+            isArguments(value) || isBuffer(value))) {
+        return !value.length;
+      }
+      if (isObjectLike(value)) {
+        var tag = getTag(value);
+        if (tag == mapTag || tag == setTag) {
+          return !value.size;
+        }
+      }
+      for (var key in value) {
+        if (hasOwnProperty.call(value, key)) {
+          return false;
+        }
+      }
+      return !(nonEnumShadows && keys(value).length);
+    }
+
+    /**
+     * 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 **not** supported.
+     *
+     * @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 = { 'user': 'fred' };
+     * var other = { 'user': 'fred' };
+     *
+     * _.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, 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;
+      }
+      return (objectToString.call(value) == errorTag) ||
+        (typeof value.message == 'string' && typeof value.name == 'string');
+    }
+
+    /**
+     * 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.MAX_VALUE);
+     * // => true
+     *
+     * _.isFinite(3.14);
+     * // => true
+     *
+     * _.isFinite(Infinity);
+     * // => 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isFunction(_);
+     * // => true
+     *
+     * _.isFunction(/abc/);
+     * // => false
+     */
+    function isFunction(value) {
+      // The use of `Object#toString` avoids issues with the `typeof` operator
+      // in Safari 8 which returns 'object' for typed array and weak map constructors,
+      // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+      var tag = isObject(value) ? objectToString.call(value) : '';
+      return tag == funcTag || tag == genTag;
+    }
+
+    /**
+     * 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 function is loosely based on
+     * [`ToLength`](http://ecma-international.org/ecma-262/6.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/6.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 && (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 && 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isMap(new Map);
+     * // => true
+     *
+     * _.isMap(new WeakMap);
+     * // => false
+     */
+    function isMap(value) {
+      return isObjectLike(value) && getTag(value) == mapTag;
+    }
+
+    /**
+     * Performs a partial deep comparison between `object` and `source` to
+     * determine if `object` contains equivalent property values. This method is
+     * equivalent to a `_.matches` function when `source` is partially applied.
+     *
+     * **Note:** This method supports comparing the same values as `_.isEqual`.
+     *
+     * @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 = { 'user': 'fred', 'age': 40 };
+     *
+     * _.isMatch(object, { 'age': 40 });
+     * // => true
+     *
+     * _.isMatch(object, { 'age': 36 });
+     * // => 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 native function.
+     *
+     * @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 (!isObject(value)) {
+        return false;
+      }
+      var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
+      return pattern.test(toSource(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 correctly classified,
+     *  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) && objectToString.call(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) ||
+          objectToString.call(value) != objectTag || isHostObject(value)) {
+        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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isRegExp(/abc/);
+     * // => true
+     *
+     * _.isRegExp('/abc/');
+     * // => false
+     */
+    function isRegExp(value) {
+      return isObject(value) && objectToString.call(value) == regexpTag;
+    }
+
+    /**
+     * 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isSet(new Set);
+     * // => true
+     *
+     * _.isSet(new WeakSet);
+     * // => false
+     */
+    function isSet(value) {
+      return isObjectLike(value) && getTag(value) == setTag;
+    }
+
+    /**
+     * 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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isString('abc');
+     * // => true
+     *
+     * _.isString(1);
+     * // => false
+     */
+    function isString(value) {
+      return typeof value == 'string' ||
+        (!isArray(value) && isObjectLike(value) && objectToString.call(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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isSymbol(Symbol.iterator);
+     * // => true
+     *
+     * _.isSymbol('abc');
+     * // => false
+     */
+    function isSymbol(value) {
+      return typeof value == 'symbol' ||
+        (isObjectLike(value) && objectToString.call(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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isTypedArray(new Uint8Array);
+     * // => true
+     *
+     * _.isTypedArray([]);
+     * // => false
+     */
+    function isTypedArray(value) {
+      return isObjectLike(value) &&
+        isLength(value.length) && !!typedArrayTags[objectToString.call(value)];
+    }
+
+    /**
+     * 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 correctly classified,
+     *  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 correctly classified,
+     *  else `false`.
+     * @example
+     *
+     * _.isWeakSet(new WeakSet);
+     * // => true
+     *
+     * _.isWeakSet(new Set);
+     * // => false
+     */
+    function isWeakSet(value) {
+      return isObjectLike(value) && objectToString.call(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 (iteratorSymbol && value[iteratorSymbol]) {
+        return iteratorToArray(value[iteratorSymbol]());
+      }
+      var tag = getTag(value),
+          func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values);
+
+      return func(value);
+    }
+
+    /**
+     * Converts `value` to an integer.
+     *
+     * **Note:** This function is loosely based on
+     * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.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);
+     * // => 3
+     *
+     * _.toInteger(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toInteger(Infinity);
+     * // => 1.7976931348623157e+308
+     *
+     * _.toInteger('3');
+     * // => 3
+     */
+    function toInteger(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;
+      }
+      var remainder = value % 1;
+      return value === value ? (remainder ? value - remainder : value) : 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/6.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);
+     * // => 3
+     *
+     * _.toLength(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toLength(Infinity);
+     * // => 4294967295
+     *
+     * _.toLength('3');
+     * // => 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);
+     * // => 3
+     *
+     * _.toNumber(Number.MIN_VALUE);
+     * // => 5e-324
+     *
+     * _.toNumber(Infinity);
+     * // => Infinity
+     *
+     * _.toNumber('3');
+     * // => 3
+     */
+    function toNumber(value) {
+      if (typeof value == 'number') {
+        return value;
+      }
+      if (isSymbol(value)) {
+        return NAN;
+      }
+      if (isObject(value)) {
+        var other = isFunction(value.valueOf) ? 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);
+     * // => 3
+     *
+     * _.toSafeInteger(Number.MIN_VALUE);
+     * // => 0
+     *
+     * _.toSafeInteger(Infinity);
+     * // => 9007199254740991
+     *
+     * _.toSafeInteger('3');
+     * // => 3
+     */
+    function toSafeInteger(value) {
+      return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER);
+    }
+
+    /**
+     * 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 process.
+     * @returns {string} Returns the 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.c = 3;
+     * }
+     *
+     * function Bar() {
+     *   this.e = 5;
+     * }
+     *
+     * Foo.prototype.d = 4;
+     * Bar.prototype.f = 6;
+     *
+     * _.assign({ 'a': 1 }, new Foo, new Bar);
+     * // => { 'a': 1, 'c': 3, 'e': 5 }
+     */
+    var assign = createAssigner(function(object, source) {
+      if (nonEnumShadows || 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.b = 2;
+     * }
+     *
+     * function Bar() {
+     *   this.d = 4;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     * Bar.prototype.e = 5;
+     *
+     * _.assignIn({ 'a': 1 }, new Foo, new Bar);
+     * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
+     */
+    var assignIn = createAssigner(function(object, source) {
+      if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
+        copyObject(source, keysIn(source), object);
+        return;
+      }
+      for (var key in source) {
+        assignValue(object, key, source[key]);
+      }
+    });
+
+    /**
+     * 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 of elements to pick.
+     * @returns {Array} Returns the new array of picked elements.
+     * @example
+     *
+     * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+     *
+     * _.at(object, ['a[0].b.c', 'a[1]']);
+     * // => [3, 4]
+     *
+     * _.at(['a', 'b', 'c'], 0, 2);
+     * // => ['a', 'c']
+     */
+    var at = rest(function(object, paths) {
+      return baseAt(object, baseFlatten(paths, 1));
+    });
+
+    /**
+     * 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 ? baseAssign(result, properties) : result;
+    }
+
+    /**
+     * 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({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
+     * // => { 'user': 'barney', 'age': 36 }
+     */
+    var defaults = rest(function(args) {
+      args.push(undefined, assignInDefaults);
+      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({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
+     * // => { 'user': { 'name': 'barney', 'age': 36 } }
+     *
+     */
+    var defaultsDeep = rest(function(args) {
+      args.push(undefined, mergeDefaults);
+      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 search.
+     * @param {Array|Function|Object|string} [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 baseFind(object, getIteratee(predicate, 3), baseForOwn, true);
+    }
+
+    /**
+     * 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 search.
+     * @param {Array|Function|Object|string} [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 baseFind(object, getIteratee(predicate, 3), baseForOwnRight, true);
+    }
+
+    /**
+     * 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), 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), 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));
+    }
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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 new array of property 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 new array of property 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 used 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 {Array|Function|Object|string} [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 = rest(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/6.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) {
+      var isProto = isPrototype(object);
+      if (!(isProto || isArrayLike(object))) {
+        return baseKeys(object);
+      }
+      var indexes = indexKeys(object),
+          skipIndexes = !!indexes,
+          result = indexes || [],
+          length = result.length;
+
+      for (var key in object) {
+        if (baseHas(object, key) &&
+            !(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+            !(isProto && key == 'constructor')) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * 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) {
+      var index = -1,
+          isProto = isPrototype(object),
+          props = baseKeysIn(object),
+          propsLength = props.length,
+          indexes = indexKeys(object),
+          skipIndexes = !!indexes,
+          result = indexes || [],
+          length = result.length;
+
+      while (++index < propsLength) {
+        var key = props[index];
+        if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
+            !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+          result.push(key);
+        }
+      }
+      return result;
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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) {
+        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 {Array|Function|Object|string} [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) {
+        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 users = {
+     *   'data': [{ 'user': 'barney' }, { 'user': 'fred' }]
+     * };
+     *
+     * var ages = {
+     *   'data': [{ 'age': 36 }, { 'age': 40 }]
+     * };
+     *
+     * _.merge(users, ages);
+     * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] }
+     */
+    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 seven 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 = {
+     *   'fruits': ['apple'],
+     *   'vegetables': ['beet']
+     * };
+     *
+     * var other = {
+     *   'fruits': ['banana'],
+     *   'vegetables': ['carrot']
+     * };
+     *
+     * _.mergeWith(object, other, customizer);
+     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] }
+     */
+    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 string keyed properties of `object` that are
+     * not omitted.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Object
+     * @param {Object} object The source object.
+     * @param {...(string|string[])} [props] The property identifiers 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 = rest(function(object, props) {
+      if (object == null) {
+        return {};
+      }
+      props = arrayMap(baseFlatten(props, 1), toKey);
+      return basePick(object, baseDifference(getAllKeysIn(object), props));
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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) {
+      predicate = getIteratee(predicate);
+      return basePickBy(object, function(value, key) {
+        return !predicate(value, key);
+      });
+    }
+
+    /**
+     * 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[])} [props] The property identifiers 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 = rest(function(object, props) {
+      return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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) {
+      return object == null ? {} : basePickBy(object, getIteratee(predicate));
+    }
+
+    /**
+     * 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 = isKey(path, object) ? [path] : castPath(path);
+
+      var index = -1,
+          length = path.length;
+
+      // Ensure the loop is entered when path is empty.
+      if (!length) {
+        object = undefined;
+        length = 1;
+      }
+      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`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias entries
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the new array of 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)
+     */
+    function toPairs(object) {
+      return baseToPairs(object, keys(object));
+    }
+
+    /**
+     * Creates an array of own and inherited enumerable string keyed-value pairs
+     * for `object` which can be consumed by `_.fromPairs`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @alias entriesIn
+     * @category Object
+     * @param {Object} object The object to query.
+     * @returns {Array} Returns the new array of key-value pairs.
+     * @example
+     *
+     * function Foo() {
+     *   this.a = 1;
+     *   this.b = 2;
+     * }
+     *
+     * Foo.prototype.c = 3;
+     *
+     * _.toPairsIn(new Foo);
+     * // => [['a', 1], ['b', 2], ['c', 1]] (iteration order is not guaranteed)
+     */
+    function toPairsIn(object) {
+      return baseToPairs(object, keysIn(object));
+    }
+
+    /**
+     * 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. 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 {Array|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) || isTypedArray(object);
+      iteratee = getIteratee(iteratee, 4);
+
+      if (accumulator == null) {
+        if (isArr || isObject(object)) {
+          var Ctor = object.constructor;
+          if (isArr) {
+            accumulator = isArray(object) ? new Ctor : [];
+          } else {
+            accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
+          }
+        } else {
+          accumulator = {};
+        }
+      }
+      (isArr ? 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 ? 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 = toNumber(start) || 0;
+      if (end === undefined) {
+        end = start;
+        start = 0;
+      } else {
+        end = toNumber(end) || 0;
+      }
+      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 = toNumber(lower) || 0;
+        if (upper === undefined) {
+          upper = lower;
+          lower = 0;
+        } else {
+          upper = toNumber(upper) || 0;
+        }
+      }
+      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 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+     * 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(reLatin1, 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 search.
+     * @param {string} [target] The string to search for.
+     * @param {number} [position=string.length] The position to search from.
+     * @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);
+
+      position -= target.length;
+      return position >= 0 && string.indexOf(target, position) == position;
+    }
+
+    /**
+     * 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.
+     *
+     * Backticks are escaped because in IE < 9, they can break out of
+     * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+     * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
+     * [#133](https://html5sec.org/#133) of the
+     * [HTML5 Security Cheatsheet](https://html5sec.org/) 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) {
+      // Chrome fails to trim leading <BOM> whitespace characters.
+      // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details.
+      if (guard || radix == null) {
+        radix = 0;
+      } else if (radix) {
+        radix = +radix;
+      }
+      string = toString(string).replace(reTrim, '');
+      return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10));
+    }
+
+    /**
+     * 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 : nativeReplace.call(string, 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 new array of 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 == '' && reHasComplexSymbol.test(string)) {
+          return castSlice(stringToArray(string), 0, limit);
+        }
+      }
+      return nativeSplit.call(string, 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 search.
+     * @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 = baseClamp(toInteger(position), 0, string.length);
+      return string.lastIndexOf(baseToString(target), position) == position;
+    }
+
+    /**
+     * 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 delimiter as an alternative to the default "interpolate" delimiter.
+     * var compiled = _.template('hello ${ user }!');
+     * compiled({ 'user': 'pebbles' });
+     * // => 'hello pebbles!'
+     *
+     * // Use custom template delimiters.
+     * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
+     * var compiled = _.template('hello {{ user }}!');
+     * compiled({ 'user': 'mustache' });
+     * // => 'hello mustache!'
+     *
+     * // 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 the `source` property to inline compiled templates for meaningful
+     * // line numbers in error messages and stack traces.
+     * fs.writeFileSync(path.join(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, assignInDefaults);
+
+      var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults),
+          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 (reHasComplexSymbol.test(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;`, `&#39;`, and `&#96;` 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) {
+        pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
+      }
+      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 = rest(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',
+     *   'onClick': function() {
+     *     console.log('clicked ' + this.label);
+     *   }
+     * };
+     *
+     * _.bindAll(view, 'onClick');
+     * jQuery(element).on('click', view.onClick);
+     * // => Logs 'clicked docs' when clicked.
+     */
+    var bindAll = rest(function(object, methodNames) {
+      arrayEach(baseFlatten(methodNames, 1), function(key) {
+        key = toKey(key);
+        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 function.
+     * @example
+     *
+     * var func = _.cond([
+     *   [_.matches({ 'a': 1 }),           _.constant('matches A')],
+     *   [_.conforms({ 'b': _.isNumber }), _.constant('matches B')],
+     *   [_.constant(true),                _.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 ? pairs.length : 0,
+          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 rest(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`.
+     *
+     * @static
+     * @memberOf _
+     * @since 4.0.0
+     * @category Util
+     * @param {Object} source The object of property predicates to conform to.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36 },
+     *   { 'user': 'fred',   'age': 40 }
+     * ];
+     *
+     * _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) }));
+     * // => [{ 'user': 'fred', 'age': 40 }]
+     */
+    function conforms(source) {
+      return baseConforms(baseClone(source, true));
+    }
+
+    /**
+     * 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 function.
+     * @example
+     *
+     * var object = { 'user': 'fred' };
+     * var getter = _.constant(object);
+     *
+     * getter() === object;
+     * // => true
+     */
+    function constant(value) {
+      return function() {
+        return 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] Functions to invoke.
+     * @returns {Function} Returns the new 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] Functions to invoke.
+     * @returns {Function} Returns the new 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 given to it.
+     *
+     * @static
+     * @since 0.1.0
+     * @memberOf _
+     * @category Util
+     * @param {*} value Any value.
+     * @returns {*} Returns `value`.
+     * @example
+     *
+     * var object = { 'user': 'fred' };
+     *
+     * _.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, true));
+    }
+
+    /**
+     * 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`. The created function is equivalent to
+     * `_.isMatch` with a `source` partially applied.
+     *
+     * **Note:** This method supports comparing the same values as `_.isEqual`.
+     *
+     * @static
+     * @memberOf _
+     * @since 3.0.0
+     * @category Util
+     * @param {Object} source The object of property values to match.
+     * @returns {Function} Returns the new function.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney', 'age': 36, 'active': true },
+     *   { 'user': 'fred',   'age': 40, 'active': false }
+     * ];
+     *
+     * _.filter(users, _.matches({ 'age': 40, 'active': false }));
+     * // => [{ 'user': 'fred', 'age': 40, 'active': false }]
+     */
+    function matches(source) {
+      return baseMatches(baseClone(source, true));
+    }
+
+    /**
+     * 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:** This method supports comparing the same values as `_.isEqual`.
+     *
+     * @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 function.
+     * @example
+     *
+     * var users = [
+     *   { 'user': 'barney' },
+     *   { 'user': 'fred' }
+     * ];
+     *
+     * _.find(users, _.matchesProperty('user', 'fred'));
+     * // => { 'user': 'fred' }
+     */
+    function matchesProperty(path, srcValue) {
+      return baseMatchesProperty(path, baseClone(srcValue, true));
+    }
+
+    /**
+     * 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 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 = rest(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 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 = rest(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;
+    }
+
+    /**
+     * A no-operation function that returns `undefined` regardless of the
+     * arguments it receives.
+     *
+     * @static
+     * @memberOf _
+     * @since 2.3.0
+     * @category Util
+     * @example
+     *
+     * var object = { 'user': 'fred' };
+     *
+     * _.noop(object) === undefined;
+     * // => true
+     */
+    function noop() {
+      // No operation performed.
+    }
+
+    /**
+     * Creates a function that returns its nth argument. 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 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 rest(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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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 {...(Array|Array[]|Function|Function[]|Object|Object[]|string|string[])}
+     *  [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 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 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 new array 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 new array 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);
+
+    /**
+     * 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(true));
+     * // => [true, true, true, true]
+     */
+    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']
+     *
+     * var path = ['a', 'b', 'c'],
+     *     newPath = _.toPath(path);
+     *
+     * console.log(newPath);
+     * // => ['a', 'b', 'c']
+     *
+     * console.log(path === newPath);
+     * // => false
+     */
+    function toPath(value) {
+      if (isArray(value)) {
+        return arrayMap(value, toKey);
+      }
+      return isSymbol(value) ? [value] : copyArray(stringToPath(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;
+    });
+
+    /**
+     * 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;
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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), 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 {Array|Function|Object|string} [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));
+    }
+
+    /**
+     * 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 {Array|Function|Object|string} [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), 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;
+    });
+
+    /**
+     * 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;
+    });
+
+    /**
+     * 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 {Array|Function|Object|string} [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))
+        : 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.deburr = deburr;
+    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.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.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) {
+        var filtered = this.__filtered__;
+        if (filtered && !index) {
+          return new LazyWrapper(this);
+        }
+        n = n === undefined ? 1 : nativeMax(toInteger(n), 0);
+
+        var result = this.clone();
+        if (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 = rest(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) {
+      predicate = getIteratee(predicate, 3);
+      return this.filter(function(value) {
+        return !predicate(value);
+      });
+    };
+
+    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[createHybridWrapper(undefined, 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;
+
+    if (iteratorSymbol) {
+      lodash.prototype[iteratorSymbol] = wrapperToIterator;
+    }
+    return lodash;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // Export lodash.
+  var _ = runInContext();
+
+  // Expose Lodash on the free variable `window` or `self` when available so it's
+  // globally accessible, even when bundled with Browserify, Webpack, etc. This
+  // also prevents errors in cases where 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.
+  (freeWindow || freeSelf || {})._ = _;
+
+  // Some AMD build optimizers like r.js check for condition patterns like the following:
+  if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
+    // Define as an anonymous module so, through path mapping, it can be
+    // referenced as the "underscore" module.
+    define(function() {
+      return _;
+    });
+  }
+  // Check for `exports` after `define` in case a build optimizer adds an `exports` object.
+  else if (freeExports && freeModule) {
+    // Export for Node.js.
+    if (moduleExports) {
+      (freeModule.exports = _)._ = _;
+    }
+    // Export for CommonJS support.
+    freeExports._ = _;
+  }
+  else {
+    // Export to the global object.
+    root._ = _;
+  }
+}.call(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/package.json b/views/ngXosViews/serviceGrid/src/vendor/lodash/package.json
new file mode 100644
index 0000000..914499d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/package.json
@@ -0,0 +1,52 @@
+{
+  "name": "lodash",
+  "version": "4.11.2",
+  "license": "MIT",
+  "private": true,
+  "main": "lodash.js",
+  "scripts": {
+    "build": "npm run build:main && npm run build:fp",
+    "build:fp": "node lib/fp/build-dist.js",
+    "build:fp-modules": "node lib/fp/build-modules.js",
+    "build:main": "node lib/main/build-dist.js",
+    "build:main-modules": "node lib/main/build-modules.js",
+    "doc": "node lib/main/build-doc github",
+    "doc:fp": "node lib/fp/build-doc",
+    "doc:site": "node lib/main/build-doc site",
+    "pretest": "npm run build",
+    "style": "npm run style:main && npm run style:fp && npm run style:perf && npm run style:test",
+    "style:fp": "jscs fp/*.js lib/**/*.js",
+    "style:main": "jscs lodash.js",
+    "style:perf": "jscs perf/*.js perf/**/*.js",
+    "style:test": "jscs test/*.js test/**/*.js",
+    "test": "npm run test:main && npm run test:fp",
+    "test:fp": "node test/test-fp",
+    "test:main": "node test/test",
+    "validate": "npm run style && npm run test"
+  },
+  "devDependencies": {
+    "async": "^1.5.2",
+    "benchmark": "^2.1.0",
+    "chalk": "^1.1.3",
+    "codecov.io": "~0.1.6",
+    "coveralls": "^2.11.9",
+    "curl-amd": "~0.8.12",
+    "docdown": "~0.5.1",
+    "dojo": "^1.11.1",
+    "ecstatic": "^1.4.0",
+    "fs-extra": "~0.28.0",
+    "glob": "^7.0.3",
+    "istanbul": "0.4.3",
+    "jquery": "^2.2.3",
+    "jscs": "^3.0.1",
+    "lodash": "4.10.0",
+    "platform": "^1.3.1",
+    "qunit-extras": "^1.5.0",
+    "qunitjs": "~1.23.1",
+    "request": "^2.69.0",
+    "requirejs": "^2.2.0",
+    "sauce-tunnel": "^2.4.0",
+    "uglify-js": "2.6.2",
+    "webpack": "^1.12.15"
+  }
+}
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/asset/perf-ui.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/asset/perf-ui.js
new file mode 100644
index 0000000..e3ed64b
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/asset/perf-ui.js
@@ -0,0 +1,131 @@
+;(function(window) {
+  'use strict';
+
+  /** The base path of the lodash builds. */
+  var basePath = '../';
+
+  /** The lodash build to load. */
+  var build = (build = /build=([^&]+)/.exec(location.search)) && decodeURIComponent(build[1]);
+
+  /** The other library to load. */
+  var other = (other = /other=([^&]+)/.exec(location.search)) && decodeURIComponent(other[1]);
+
+  /** The `ui` object. */
+  var ui = {};
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Registers an event listener on an element.
+   *
+   * @private
+   * @param {Element} element The element.
+   * @param {string} eventName The name of the event.
+   * @param {Function} handler The event handler.
+   * @returns {Element} The element.
+   */
+  function addListener(element, eventName, handler) {
+    if (typeof element.addEventListener != 'undefined') {
+      element.addEventListener(eventName, handler, false);
+    } else if (typeof element.attachEvent != 'undefined') {
+      element.attachEvent('on' + eventName, handler);
+    }
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // Initialize controls.
+  addListener(window, 'load', function() {
+    function eventHandler(event) {
+      var buildIndex = buildList.selectedIndex,
+          otherIndex = otherList.selectedIndex,
+          search = location.search.replace(/^\?|&?(?:build|other)=[^&]*&?/g, '');
+
+      if (event.stopPropagation) {
+        event.stopPropagation();
+      } else {
+        event.cancelBubble = true;
+      }
+      location.href =
+        location.href.split('?')[0] + '?' +
+        (search ? search + '&' : '') +
+        'build=' + (buildIndex < 0 ? build : buildList[buildIndex].value) + '&' +
+        'other=' + (otherIndex < 0 ? other : otherList[otherIndex].value);
+    }
+
+    var span1 = document.createElement('span');
+    span1.style.cssText = 'float:right';
+    span1.innerHTML =
+      '<label for="perf-build">Build: </label>' +
+      '<select id="perf-build">' +
+      '<option value="lodash">lodash</option>' +
+      '</select>';
+
+    var span2 = document.createElement('span');
+    span2.style.cssText = 'float:right';
+    span2.innerHTML =
+      '<label for="perf-other">Other Library: </label>' +
+      '<select id="perf-other">' +
+      '<option value="underscore-dev">Underscore (development)</option>' +
+      '<option value="underscore">Underscore (production)</option>' +
+      '<option value="lodash">lodash</option>' +
+      '</select>';
+
+    var buildList = span1.lastChild,
+        otherList = span2.lastChild,
+        toolbar = document.getElementById('perf-toolbar');
+
+    toolbar.appendChild(span2);
+    toolbar.appendChild(span1);
+
+    buildList.selectedIndex = (function() {
+      switch (build) {
+        case 'lodash':
+        case null:                return 0;
+      }
+      return -1;
+    }());
+
+    otherList.selectedIndex = (function() {
+      switch (other) {
+        case 'underscore-dev':    return 0;
+        case 'lodash':            return 2;
+        case 'underscore':
+        case null:                return 1;
+      }
+      return -1;
+    }());
+
+    addListener(buildList, 'change', eventHandler);
+    addListener(otherList, 'change', eventHandler);
+  });
+
+  // The lodash build file path.
+  ui.buildPath = (function() {
+    var result;
+    switch (build) {
+      case null:                build  = 'lodash';
+      case 'lodash':            result = 'dist/lodash.min.js'; break;
+      default:                  return build;
+    }
+    return basePath + result;
+  }());
+
+  // The other library file path.
+  ui.otherPath = (function() {
+    var result;
+    switch (other) {
+      case 'lodash':            result = 'dist/lodash.min.js'; break;
+      case 'underscore-dev':    result = 'vendor/underscore/underscore.js'; break;
+      case null:                other  = 'underscore';
+      case 'underscore':        result = 'vendor/underscore/underscore-min.js'; break;
+      default:                  return other;
+    }
+    return basePath + result;
+  }());
+
+  ui.urlParams = { 'build': build, 'other': other };
+
+  window.ui = ui;
+
+}(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/index.html b/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/index.html
new file mode 100644
index 0000000..16d41bf
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/index.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>lodash Performance Suite</title>
+    <style>
+      html, body {
+        margin: 0;
+        padding: 0;
+        height: 100%;
+      }
+      #FirebugUI {
+        top: 2em;
+      }
+      #perf-toolbar {
+        background-color: #EEE;
+        color: #5E740B;
+        font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
+        font-size: small;
+        padding: 0.5em 0 0.5em 2em;
+        overflow: hidden;
+      }
+    </style>
+  </head>
+  <body>
+    <div id="perf-toolbar"></div>
+    <script src="../lodash.js"></script>
+    <script src="../node_modules/platform/platform.js"></script>
+    <script src="../node_modules/benchmark/benchmark.js"></script>
+    <script src="../vendor/firebug-lite/src/firebug-lite-debug.js"></script>
+    <script src="./asset/perf-ui.js"></script>
+    <script>
+      document.write('<script src="' + ui.buildPath + '"><\/script>');
+    </script>
+    <script>
+      var lodash = _.noConflict();
+    </script>
+    <script>
+      document.write('<script src="' + ui.otherPath + '"><\/script>');
+    </script>
+    <script src="perf.js"></script>
+    <script>
+      (function() {
+        var measured,
+            perfNow,
+            begin = new Date;
+
+        function init() {
+          var fbUI = document.getElementById('FirebugUI'),
+              fbDoc = fbUI && (fbDoc = fbUI.contentWindow || fbUI.contentDocument).document || fbDoc,
+              fbCommandLine = fbDoc && fbDoc.getElementById('fbCommandLine');
+
+          if (!fbCommandLine) {
+            return setTimeout(init, 15);
+          }
+          fbUI.style.height = (
+            Math.max(document.documentElement.clientHeight, document.body.clientHeight) -
+            document.getElementById('perf-toolbar').clientHeight
+          ) + 'px';
+
+          fbDoc.body.style.height = fbDoc.documentElement.style.height = '100%';
+          setTimeout(run, 15);
+        }
+
+        window.onload = init;
+      }());
+    </script>
+  </body>
+</html>
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/perf.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/perf.js
new file mode 100644
index 0000000..baee142
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/perf/perf.js
@@ -0,0 +1,1977 @@
+;(function() {
+
+  /** Used to access the Firebug Lite panel (set by `run`). */
+  var fbPanel;
+
+  /** Used as a safe reference for `undefined` in pre ES5 environments. */
+  var undefined;
+
+  /** Used as a reference to the global object. */
+  var root = typeof global == 'object' && global || this;
+
+  /** Method and object shortcuts. */
+  var phantom = root.phantom,
+      amd = root.define && define.amd,
+      argv = root.process && process.argv,
+      document = !phantom && root.document,
+      noop = function() {},
+      params = root.arguments,
+      system = root.system;
+
+  /** Add `console.log()` support for Rhino and RingoJS. */
+  var console = root.console || (root.console = { 'log': root.print });
+
+  /** The file path of the lodash file to test. */
+  var filePath = (function() {
+    var min = 0,
+        result = [];
+
+    if (phantom) {
+      result = params = phantom.args;
+    } else if (system) {
+      min = 1;
+      result = params = system.args;
+    } else if (argv) {
+      min = 2;
+      result = params = argv;
+    } else if (params) {
+      result = params;
+    }
+    var last = result[result.length - 1];
+    result = (result.length > min && !/perf(?:\.js)?$/.test(last)) ? last : '../lodash.js';
+
+    if (!amd) {
+      try {
+        result = require('fs').realpathSync(result);
+      } catch (e) {}
+
+      try {
+        result = require.resolve(result);
+      } catch (e) {}
+    }
+    return result;
+  }());
+
+  /** Used to match path separators. */
+  var rePathSeparator = /[\/\\]/;
+
+  /** Used to detect primitive types. */
+  var rePrimitive = /^(?:boolean|number|string|undefined)$/;
+
+  /** Used to match RegExp special characters. */
+  var reSpecialChars = /[.*+?^=!:${}()|[\]\/\\]/g;
+
+  /** The `ui` object. */
+  var ui = root.ui || (root.ui = {
+    'buildPath': basename(filePath, '.js'),
+    'otherPath': 'underscore'
+  });
+
+  /** The lodash build basename. */
+  var buildName = root.buildName = basename(ui.buildPath, '.js');
+
+  /** The other library basename. */
+  var otherName = root.otherName = (function() {
+    var result = basename(ui.otherPath, '.js');
+    return result + (result == buildName ? ' (2)' : '');
+  }());
+
+  /** Used to score performance. */
+  var score = { 'a': [], 'b': [] };
+
+  /** Used to queue benchmark suites. */
+  var suites = [];
+
+  /** Use a single "load" function. */
+  var load = (typeof require == 'function' && !amd)
+    ? require
+    : noop;
+
+  /** Load lodash. */
+  var lodash = root.lodash || (root.lodash = (
+    lodash = load(filePath) || root._,
+    lodash = lodash._ || lodash,
+    (lodash.runInContext ? lodash.runInContext(root) : lodash),
+    lodash.noConflict()
+  ));
+
+  /** Load Underscore. */
+  var _ = root.underscore || (root.underscore = (
+    _ = load('../vendor/underscore/underscore.js') || root._,
+    _._ || _
+  ));
+
+  /** Load Benchmark.js. */
+  var Benchmark = root.Benchmark || (root.Benchmark = (
+    Benchmark = load('../node_modules/benchmark/benchmark.js') || root.Benchmark,
+    Benchmark = Benchmark.Benchmark || Benchmark,
+    Benchmark.runInContext(lodash.extend({}, root, { '_': lodash }))
+  ));
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Gets the basename of the given `filePath`. If the file `extension` is passed,
+   * it will be removed from the basename.
+   *
+   * @private
+   * @param {string} path The file path to inspect.
+   * @param {string} extension The extension to remove.
+   * @returns {string} Returns the basename.
+   */
+  function basename(filePath, extension) {
+    var result = (filePath || '').split(rePathSeparator).pop();
+    return (arguments.length < 2)
+      ? result
+      : result.replace(RegExp(extension.replace(reSpecialChars, '\\$&') + '$'), '');
+  }
+
+  /**
+   * Computes the geometric mean (log-average) of an array of values.
+   * See http://en.wikipedia.org/wiki/Geometric_mean#Relationship_with_arithmetic_mean_of_logarithms.
+   *
+   * @private
+   * @param {Array} array The array of values.
+   * @returns {number} The geometric mean.
+   */
+  function getGeometricMean(array) {
+    return Math.pow(Math.E, lodash.reduce(array, function(sum, x) {
+      return sum + Math.log(x);
+    }, 0) / array.length) || 0;
+  }
+
+  /**
+   * Gets the Hz, i.e. operations per second, of `bench` adjusted for the
+   * margin of error.
+   *
+   * @private
+   * @param {Object} bench The benchmark object.
+   * @returns {number} Returns the adjusted Hz.
+   */
+  function getHz(bench) {
+    var result = 1 / (bench.stats.mean + bench.stats.moe);
+    return isFinite(result) ? result : 0;
+  }
+
+  /**
+   * Host objects can return type values that are different from their actual
+   * data type. The objects we are concerned with usually return non-primitive
+   * types of "object", "function", or "unknown".
+   *
+   * @private
+   * @param {*} object The owner of the property.
+   * @param {string} property The property to check.
+   * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`.
+   */
+  function isHostType(object, property) {
+    if (object == null) {
+      return false;
+    }
+    var type = typeof object[property];
+    return !rePrimitive.test(type) && (type != 'object' || !!object[property]);
+  }
+
+  /**
+   * Logs text to the console.
+   *
+   * @private
+   * @param {string} text The text to log.
+   */
+  function log(text) {
+    console.log(text + '');
+    if (fbPanel) {
+      // Scroll the Firebug Lite panel down.
+      fbPanel.scrollTop = fbPanel.scrollHeight;
+    }
+  }
+
+  /**
+   * Runs all benchmark suites.
+   *
+   * @private (@public in the browser)
+   */
+  function run() {
+    fbPanel = (fbPanel = root.document && document.getElementById('FirebugUI')) &&
+      (fbPanel = (fbPanel = fbPanel.contentWindow || fbPanel.contentDocument).document || fbPanel) &&
+      fbPanel.getElementById('fbPanel1');
+
+    log('\nSit back and relax, this may take a while.');
+    suites[0].run({ 'async': true });
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  lodash.extend(Benchmark.Suite.options, {
+    'onStart': function() {
+      log('\n' + this.name + ':');
+    },
+    'onCycle': function(event) {
+      log(event.target);
+    },
+    'onComplete': function() {
+      for (var index = 0, length = this.length; index < length; index++) {
+        var bench = this[index];
+        if (bench.error) {
+          var errored = true;
+        }
+      }
+      if (errored) {
+        log('There was a problem, skipping...');
+      }
+      else {
+        var formatNumber = Benchmark.formatNumber,
+            fastest = this.filter('fastest'),
+            fastestHz = getHz(fastest[0]),
+            slowest = this.filter('slowest'),
+            slowestHz = getHz(slowest[0]),
+            aHz = getHz(this[0]),
+            bHz = getHz(this[1]);
+
+        if (fastest.length > 1) {
+          log('It\'s too close to call.');
+          aHz = bHz = slowestHz;
+        }
+        else {
+          var percent = ((fastestHz / slowestHz) - 1) * 100;
+
+          log(
+            fastest[0].name + ' is ' +
+            formatNumber(percent < 1 ? percent.toFixed(2) : Math.round(percent)) +
+            '% faster.'
+          );
+        }
+        // Add score adjusted for margin of error.
+        score.a.push(aHz);
+        score.b.push(bHz);
+      }
+      // Remove current suite from queue.
+      suites.shift();
+
+      if (suites.length) {
+        // Run next suite.
+        suites[0].run({ 'async': true });
+      }
+      else {
+        var aMeanHz = getGeometricMean(score.a),
+            bMeanHz = getGeometricMean(score.b),
+            fastestMeanHz = Math.max(aMeanHz, bMeanHz),
+            slowestMeanHz = Math.min(aMeanHz, bMeanHz),
+            xFaster = fastestMeanHz / slowestMeanHz,
+            percentFaster = formatNumber(Math.round((xFaster - 1) * 100)),
+            message = 'is ' + percentFaster + '% ' + (xFaster == 1 ? '' : '(' + formatNumber(xFaster.toFixed(2)) + 'x) ') + 'faster than';
+
+        // Report results.
+        if (aMeanHz >= bMeanHz) {
+          log('\n' + buildName + ' ' + message + ' ' + otherName + '.');
+        } else {
+          log('\n' + otherName + ' ' + message + ' ' + buildName + '.');
+        }
+      }
+    }
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  lodash.extend(Benchmark.options, {
+    'async': true,
+    'setup': '\
+      var _ = global.underscore,\
+          lodash = global.lodash,\
+          belt = this.name == buildName ? lodash : _;\
+      \
+      var date = new Date,\
+          limit = 50,\
+          regexp = /x/,\
+          object = {},\
+          objects = Array(limit),\
+          numbers = Array(limit),\
+          fourNumbers = [5, 25, 10, 30],\
+          nestedNumbers = [1, [2], [3, [[4]]]],\
+          nestedObjects = [{}, [{}], [{}, [[{}]]]],\
+          twoNumbers = [12, 23];\
+      \
+      for (var index = 0; index < limit; index++) {\
+        numbers[index] = index;\
+        object["key" + index] = index;\
+        objects[index] = { "num": index };\
+      }\
+      var strNumbers = numbers + "";\
+      \
+      if (typeof assign != "undefined") {\
+        var _assign = _.assign || _.extend,\
+            lodashAssign = lodash.assign;\
+      }\
+      if (typeof bind != "undefined") {\
+        var thisArg = { "name": "fred" };\
+        \
+        var func = function(greeting, punctuation) {\
+          return (greeting || "hi") + " " + this.name + (punctuation || ".");\
+        };\
+        \
+        var _boundNormal = _.bind(func, thisArg),\
+            _boundMultiple = _boundNormal,\
+            _boundPartial = _.bind(func, thisArg, "hi");\
+        \
+        var lodashBoundNormal = lodash.bind(func, thisArg),\
+            lodashBoundMultiple = lodashBoundNormal,\
+            lodashBoundPartial = lodash.bind(func, thisArg, "hi");\
+        \
+        for (index = 0; index < 10; index++) {\
+          _boundMultiple = _.bind(_boundMultiple, { "name": "fred" + index });\
+          lodashBoundMultiple = lodash.bind(lodashBoundMultiple, { "name": "fred" + index });\
+        }\
+      }\
+      if (typeof bindAll != "undefined") {\
+        var bindAllCount = -1,\
+            bindAllObjects = Array(this.count);\
+        \
+        var funcNames = belt.reject(belt.functions(belt).slice(0, 40), function(funcName) {\
+          return /^_/.test(funcName);\
+        });\
+        \
+        // Potentially expensive.\n\
+        for (index = 0; index < this.count; index++) {\
+          bindAllObjects[index] = belt.reduce(funcNames, function(object, funcName) {\
+            object[funcName] = belt[funcName];\
+            return object;\
+          }, {});\
+        }\
+      }\
+      if (typeof chaining != "undefined") {\
+        var even = function(v) { return v % 2 == 0; },\
+            square = function(v) { return v * v; };\
+        \
+        var largeArray = belt.range(10000),\
+            _chaining = _(largeArray).chain(),\
+            lodashChaining = lodash(largeArray).chain();\
+      }\
+      if (typeof compact != "undefined") {\
+        var uncompacted = numbers.slice();\
+        uncompacted[2] = false;\
+        uncompacted[6] = null;\
+        uncompacted[18] = "";\
+      }\
+      if (typeof flowRight != "undefined") {\
+        var compAddOne = function(n) { return n + 1; },\
+            compAddTwo = function(n) { return n + 2; },\
+            compAddThree = function(n) { return n + 3; };\
+        \
+        var _composed = _.flowRight && _.flowRight(compAddThree, compAddTwo, compAddOne),\
+            lodashComposed = lodash.flowRight && lodash.flowRight(compAddThree, compAddTwo, compAddOne);\
+      }\
+      if (typeof countBy != "undefined" || typeof omit != "undefined") {\
+        var wordToNumber = {\
+          "one": 1,\
+          "two": 2,\
+          "three": 3,\
+          "four": 4,\
+          "five": 5,\
+          "six": 6,\
+          "seven": 7,\
+          "eight": 8,\
+          "nine": 9,\
+          "ten": 10,\
+          "eleven": 11,\
+          "twelve": 12,\
+          "thirteen": 13,\
+          "fourteen": 14,\
+          "fifteen": 15,\
+          "sixteen": 16,\
+          "seventeen": 17,\
+          "eighteen": 18,\
+          "nineteen": 19,\
+          "twenty": 20,\
+          "twenty-one": 21,\
+          "twenty-two": 22,\
+          "twenty-three": 23,\
+          "twenty-four": 24,\
+          "twenty-five": 25,\
+          "twenty-six": 26,\
+          "twenty-seven": 27,\
+          "twenty-eight": 28,\
+          "twenty-nine": 29,\
+          "thirty": 30,\
+          "thirty-one": 31,\
+          "thirty-two": 32,\
+          "thirty-three": 33,\
+          "thirty-four": 34,\
+          "thirty-five": 35,\
+          "thirty-six": 36,\
+          "thirty-seven": 37,\
+          "thirty-eight": 38,\
+          "thirty-nine": 39,\
+          "forty": 40\
+        };\
+        \
+        var words = belt.keys(wordToNumber).slice(0, limit);\
+      }\
+      if (typeof flatten != "undefined") {\
+        var _flattenDeep = _.flatten([[1]])[0] !== 1,\
+            lodashFlattenDeep = lodash.flatten([[1]])[0] !== 1;\
+      }\
+      if (typeof isEqual != "undefined") {\
+        var objectOfPrimitives = {\
+          "boolean": true,\
+          "number": 1,\
+          "string": "a"\
+        };\
+        \
+        var objectOfObjects = {\
+          "boolean": new Boolean(true),\
+          "number": new Number(1),\
+          "string": new String("a")\
+        };\
+        \
+        var objectOfObjects2 = {\
+          "boolean": new Boolean(true),\
+          "number": new Number(1),\
+          "string": new String("A")\
+        };\
+        \
+        var object2 = {},\
+            object3 = {},\
+            objects2 = Array(limit),\
+            objects3 = Array(limit),\
+            numbers2 = Array(limit),\
+            numbers3 = Array(limit),\
+            nestedNumbers2 = [1, [2], [3, [[4]]]],\
+            nestedNumbers3 = [1, [2], [3, [[6]]]];\
+        \
+        for (index = 0; index < limit; index++) {\
+          object2["key" + index] = index;\
+          object3["key" + index] = index;\
+          objects2[index] = { "num": index };\
+          objects3[index] = { "num": index };\
+          numbers2[index] = index;\
+          numbers3[index] = index;\
+        }\
+        object3["key" + (limit - 1)] = -1;\
+        objects3[limit - 1].num = -1;\
+        numbers3[limit - 1] = -1;\
+      }\
+      if (typeof matches != "undefined") {\
+        var source = { "num": 9 };\
+        \
+        var _matcher = (_.matches || _.noop)(source),\
+            lodashMatcher = (lodash.matches || lodash.noop)(source);\
+      }\
+      if (typeof multiArrays != "undefined") {\
+        var twentyValues = belt.shuffle(belt.range(20)),\
+            fortyValues = belt.shuffle(belt.range(40)),\
+            hundredSortedValues = belt.range(100),\
+            hundredValues = belt.shuffle(hundredSortedValues),\
+            hundredValues2 = belt.shuffle(hundredValues),\
+            hundredTwentyValues = belt.shuffle(belt.range(120)),\
+            hundredTwentyValues2 = belt.shuffle(hundredTwentyValues),\
+            twoHundredValues = belt.shuffle(belt.range(200)),\
+            twoHundredValues2 = belt.shuffle(twoHundredValues);\
+      }\
+      if (typeof partial != "undefined") {\
+        var func = function(greeting, punctuation) {\
+          return greeting + " fred" + (punctuation || ".");\
+        };\
+        \
+        var _partial = _.partial(func, "hi"),\
+            lodashPartial = lodash.partial(func, "hi");\
+      }\
+      if (typeof template != "undefined") {\
+        var tplData = {\
+          "header1": "Header1",\
+          "header2": "Header2",\
+          "header3": "Header3",\
+          "header4": "Header4",\
+          "header5": "Header5",\
+          "header6": "Header6",\
+          "list": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]\
+        };\
+        \
+        var tpl =\
+          "<div>" +\
+          "<h1 class=\'header1\'><%= header1 %></h1>" +\
+          "<h2 class=\'header2\'><%= header2 %></h2>" +\
+          "<h3 class=\'header3\'><%= header3 %></h3>" +\
+          "<h4 class=\'header4\'><%= header4 %></h4>" +\
+          "<h5 class=\'header5\'><%= header5 %></h5>" +\
+          "<h6 class=\'header6\'><%= header6 %></h6>" +\
+          "<ul class=\'list\'>" +\
+          "<% for (var index = 0, length = list.length; index < length; index++) { %>" +\
+          "<li class=\'item\'><%= list[index] %></li>" +\
+          "<% } %>" +\
+          "</ul>" +\
+          "</div>";\
+        \
+        var tplVerbose =\
+          "<div>" +\
+          "<h1 class=\'header1\'><%= data.header1 %></h1>" +\
+          "<h2 class=\'header2\'><%= data.header2 %></h2>" +\
+          "<h3 class=\'header3\'><%= data.header3 %></h3>" +\
+          "<h4 class=\'header4\'><%= data.header4 %></h4>" +\
+          "<h5 class=\'header5\'><%= data.header5 %></h5>" +\
+          "<h6 class=\'header6\'><%= data.header6 %></h6>" +\
+          "<ul class=\'list\'>" +\
+          "<% for (var index = 0, length = data.list.length; index < length; index++) { %>" +\
+          "<li class=\'item\'><%= data.list[index] %></li>" +\
+          "<% } %>" +\
+          "</ul>" +\
+          "</div>";\
+        \
+        var settingsObject = { "variable": "data" };\
+        \
+        var _tpl = _.template(tpl),\
+            _tplVerbose = _.template(tplVerbose, null, settingsObject);\
+        \
+        var lodashTpl = lodash.template(tpl),\
+            lodashTplVerbose = lodash.template(tplVerbose, null, settingsObject);\
+      }\
+      if (typeof wrap != "undefined") {\
+        var add = function(a, b) {\
+          return a + b;\
+        };\
+        \
+        var average = function(func, a, b) {\
+          return (func(a, b) / 2).toFixed(2);\
+        };\
+        \
+        var _wrapped = _.wrap(add, average);\
+            lodashWrapped = lodash.wrap(add, average);\
+      }\
+      if (typeof zip != "undefined") {\
+        var unzipped = [["a", "b", "c"], [1, 2, 3], [true, false, true]];\
+      }'
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_(...).map(...).filter(...).take(...).value()`')
+      .add(buildName, {
+        'fn': 'lodashChaining.map(square).filter(even).take(100).value()',
+        'teardown': 'function chaining(){}'
+      })
+      .add(otherName, {
+        'fn': '_chaining.map(square).filter(even).take(100).value()',
+        'teardown': 'function chaining(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.assign`')
+      .add(buildName, {
+        'fn': 'lodashAssign({}, { "a": 1, "b": 2, "c": 3 })',
+        'teardown': 'function assign(){}'
+      })
+      .add(otherName, {
+        'fn': '_assign({}, { "a": 1, "b": 2, "c": 3 })',
+        'teardown': 'function assign(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.assign` with multiple sources')
+      .add(buildName, {
+        'fn': 'lodashAssign({}, { "a": 1, "b": 2 }, { "c": 3, "d": 4 })',
+        'teardown': 'function assign(){}'
+      })
+      .add(otherName, {
+        'fn': '_assign({}, { "a": 1, "b": 2 }, { "c": 3, "d": 4 })',
+        'teardown': 'function assign(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.bind` (slow path)')
+      .add(buildName, {
+        'fn': 'lodash.bind(function() { return this.name; }, { "name": "fred" })',
+        'teardown': 'function bind(){}'
+      })
+      .add(otherName, {
+        'fn': '_.bind(function() { return this.name; }, { "name": "fred" })',
+        'teardown': 'function bind(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('bound call with arguments')
+      .add(buildName, {
+        'fn': 'lodashBoundNormal("hi", "!")',
+        'teardown': 'function bind(){}'
+      })
+      .add(otherName, {
+        'fn': '_boundNormal("hi", "!")',
+        'teardown': 'function bind(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('bound and partially applied call with arguments')
+      .add(buildName, {
+        'fn': 'lodashBoundPartial("!")',
+        'teardown': 'function bind(){}'
+      })
+      .add(otherName, {
+        'fn': '_boundPartial("!")',
+        'teardown': 'function bind(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('bound multiple times')
+      .add(buildName, {
+        'fn': 'lodashBoundMultiple()',
+        'teardown': 'function bind(){}'
+      })
+      .add(otherName, {
+        'fn': '_boundMultiple()',
+        'teardown': 'function bind(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.bindAll`')
+      .add(buildName, {
+        'fn': 'lodash.bindAll(bindAllObjects[++bindAllCount], funcNames)',
+        'teardown': 'function bindAll(){}'
+      })
+      .add(otherName, {
+        'fn': '_.bindAll(bindAllObjects[++bindAllCount], funcNames)',
+        'teardown': 'function bindAll(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.clone` with an array')
+      .add(buildName, '\
+        lodash.clone(numbers)'
+      )
+      .add(otherName, '\
+        _.clone(numbers)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.clone` with an object')
+      .add(buildName, '\
+        lodash.clone(object)'
+      )
+      .add(otherName, '\
+        _.clone(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.compact`')
+      .add(buildName, {
+        'fn': 'lodash.compact(uncompacted)',
+        'teardown': 'function compact(){}'
+      })
+      .add(otherName, {
+        'fn': '_.compact(uncompacted)',
+        'teardown': 'function compact(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.countBy` with `callback` iterating an array')
+      .add(buildName, '\
+        lodash.countBy(numbers, function(num) { return num >> 1; })'
+      )
+      .add(otherName, '\
+        _.countBy(numbers, function(num) { return num >> 1; })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.countBy` with `property` name iterating an array')
+      .add(buildName, {
+        'fn': 'lodash.countBy(words, "length")',
+        'teardown': 'function countBy(){}'
+      })
+      .add(otherName, {
+        'fn': '_.countBy(words, "length")',
+        'teardown': 'function countBy(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.countBy` with `callback` iterating an object')
+      .add(buildName, {
+        'fn': 'lodash.countBy(wordToNumber, function(num) { return num >> 1; })',
+        'teardown': 'function countBy(){}'
+      })
+      .add(otherName, {
+        'fn': '_.countBy(wordToNumber, function(num) { return num >> 1; })',
+        'teardown': 'function countBy(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.defaults`')
+      .add(buildName, '\
+        lodash.defaults({ "key2": 2, "key6": 6, "key18": 18 }, object)'
+      )
+      .add(otherName, '\
+        _.defaults({ "key2": 2, "key6": 6, "key18": 18 }, object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.difference`')
+      .add(buildName, '\
+        lodash.difference(numbers, twoNumbers, fourNumbers)'
+      )
+      .add(otherName, '\
+        _.difference(numbers, twoNumbers, fourNumbers)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.difference` iterating 20 and 40 elements')
+      .add(buildName, {
+        'fn': 'lodash.difference(twentyValues, fortyValues)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.difference(twentyValues, fortyValues)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.difference` iterating 200 elements')
+      .add(buildName, {
+        'fn': 'lodash.difference(twoHundredValues, twoHundredValues2)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.difference(twoHundredValues, twoHundredValues2)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.each` iterating an array')
+      .add(buildName, '\
+        var result = [];\
+        lodash.each(numbers, function(num) {\
+          result.push(num * 2);\
+        })'
+      )
+      .add(otherName, '\
+        var result = [];\
+        _.each(numbers, function(num) {\
+          result.push(num * 2);\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.each` iterating an object')
+      .add(buildName, '\
+        var result = [];\
+        lodash.each(object, function(num) {\
+          result.push(num * 2);\
+        })'
+      )
+      .add(otherName, '\
+        var result = [];\
+        _.each(object, function(num) {\
+          result.push(num * 2);\
+        })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.every` iterating an array')
+      .add(buildName, '\
+        lodash.every(numbers, function(num) {\
+          return num < limit;\
+        })'
+      )
+      .add(otherName, '\
+        _.every(numbers, function(num) {\
+          return num < limit;\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.every` iterating an object')
+      .add(buildName, '\
+        lodash.every(object, function(num) {\
+          return num < limit;\
+        })'
+      )
+      .add(otherName, '\
+        _.every(object, function(num) {\
+          return num < limit;\
+        })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.filter` iterating an array')
+      .add(buildName, '\
+        lodash.filter(numbers, function(num) {\
+          return num % 2;\
+        })'
+      )
+      .add(otherName, '\
+        _.filter(numbers, function(num) {\
+          return num % 2;\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.filter` iterating an object')
+      .add(buildName, '\
+        lodash.filter(object, function(num) {\
+          return num % 2\
+        })'
+      )
+      .add(otherName, '\
+        _.filter(object, function(num) {\
+          return num % 2\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.filter` with `_.matches` shorthand')
+      .add(buildName, {
+        'fn': 'lodash.filter(objects, source)',
+        'teardown': 'function matches(){}'
+      })
+      .add(otherName, {
+        'fn': '_.filter(objects, source)',
+        'teardown': 'function matches(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.filter` with `_.matches` predicate')
+      .add(buildName, {
+        'fn': 'lodash.filter(objects, lodashMatcher)',
+        'teardown': 'function matches(){}'
+      })
+      .add(otherName, {
+        'fn': '_.filter(objects, _matcher)',
+        'teardown': 'function matches(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.find` iterating an array')
+      .add(buildName, '\
+        lodash.find(numbers, function(num) {\
+          return num === (limit - 1);\
+        })'
+      )
+      .add(otherName, '\
+        _.find(numbers, function(num) {\
+          return num === (limit - 1);\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.find` iterating an object')
+      .add(buildName, '\
+        lodash.find(object, function(value, key) {\
+          return /\D9$/.test(key);\
+        })'
+      )
+      .add(otherName, '\
+        _.find(object, function(value, key) {\
+          return /\D9$/.test(key);\
+        })'
+      )
+  );
+
+  // Avoid Underscore induced `OutOfMemoryError` in Rhino and Ringo.
+  suites.push(
+    Benchmark.Suite('`_.find` with `_.matches` shorthand')
+      .add(buildName, {
+        'fn': 'lodash.find(objects, source)',
+        'teardown': 'function matches(){}'
+      })
+      .add(otherName, {
+        'fn': '_.find(objects, source)',
+        'teardown': 'function matches(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.flatten`')
+      .add(buildName, {
+        'fn': 'lodash.flatten(nestedNumbers, !lodashFlattenDeep)',
+        'teardown': 'function flatten(){}'
+      })
+      .add(otherName, {
+        'fn': '_.flatten(nestedNumbers, !_flattenDeep)',
+        'teardown': 'function flatten(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.flattenDeep` nested arrays of numbers')
+      .add(buildName, {
+        'fn': 'lodash.flattenDeep(nestedNumbers)',
+        'teardown': 'function flatten(){}'
+      })
+      .add(otherName, {
+        'fn': '_.flattenDeep(nestedNumbers)',
+        'teardown': 'function flatten(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.flattenDeep` nest arrays of objects')
+      .add(buildName, {
+        'fn': 'lodash.flattenDeep(nestedObjects)',
+        'teardown': 'function flatten(){}'
+      })
+      .add(otherName, {
+        'fn': '_.flattenDeep(nestedObjects)',
+        'teardown': 'function flatten(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.flowRight`')
+      .add(buildName, {
+        'fn': 'lodash.flowRight(compAddThree, compAddTwo, compAddOne)',
+        'teardown': 'function flowRight(){}'
+      })
+      .add(otherName, {
+        'fn': '_.flowRight(compAddThree, compAddTwo, compAddOne)',
+        'teardown': 'function flowRight(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('composed call')
+      .add(buildName, {
+        'fn': 'lodashComposed(0)',
+        'teardown': 'function flowRight(){}'
+      })
+      .add(otherName, {
+        'fn': '_composed(0)',
+        'teardown': 'function flowRight(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.functions`')
+      .add(buildName, '\
+        lodash.functions(lodash)'
+      )
+      .add(otherName, '\
+        _.functions(lodash)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.groupBy` with `callback` iterating an array')
+      .add(buildName, '\
+        lodash.groupBy(numbers, function(num) { return num >> 1; })'
+      )
+      .add(otherName, '\
+        _.groupBy(numbers, function(num) { return num >> 1; })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.groupBy` with `property` name iterating an array')
+      .add(buildName, {
+        'fn': 'lodash.groupBy(words, "length")',
+        'teardown': 'function countBy(){}'
+      })
+      .add(otherName, {
+        'fn': '_.groupBy(words, "length")',
+        'teardown': 'function countBy(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.groupBy` with `callback` iterating an object')
+      .add(buildName, {
+        'fn': 'lodash.groupBy(wordToNumber, function(num) { return num >> 1; })',
+        'teardown': 'function countBy(){}'
+      })
+      .add(otherName, {
+        'fn': '_.groupBy(wordToNumber, function(num) { return num >> 1; })',
+        'teardown': 'function countBy(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.includes` searching an array')
+      .add(buildName, '\
+        lodash.includes(numbers, limit - 1)'
+      )
+      .add(otherName, '\
+        _.includes(numbers, limit - 1)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.includes` searching an object')
+      .add(buildName, '\
+        lodash.includes(object, limit - 1)'
+      )
+      .add(otherName, '\
+        _.includes(object, limit - 1)'
+      )
+  );
+
+  if (lodash.includes('ab', 'ab') && _.includes('ab', 'ab')) {
+    suites.push(
+      Benchmark.Suite('`_.includes` searching a string')
+        .add(buildName, '\
+          lodash.includes(strNumbers, "," + (limit - 1))'
+        )
+        .add(otherName, '\
+          _.includes(strNumbers, "," + (limit - 1))'
+        )
+    );
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.indexOf`')
+      .add(buildName, {
+        'fn': 'lodash.indexOf(hundredSortedValues, 99)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.indexOf(hundredSortedValues, 99)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.intersection`')
+      .add(buildName, '\
+        lodash.intersection(numbers, twoNumbers, fourNumbers)'
+      )
+      .add(otherName, '\
+        _.intersection(numbers, twoNumbers, fourNumbers)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.intersection` iterating 120 elements')
+      .add(buildName, {
+        'fn': 'lodash.intersection(hundredTwentyValues, hundredTwentyValues2)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.intersection(hundredTwentyValues, hundredTwentyValues2)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.invert`')
+      .add(buildName, '\
+        lodash.invert(object)'
+      )
+      .add(otherName, '\
+        _.invert(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.invokeMap` iterating an array')
+      .add(buildName, '\
+        lodash.invokeMap(numbers, "toFixed")'
+      )
+      .add(otherName, '\
+        _.invokeMap(numbers, "toFixed")'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.invokeMap` with arguments iterating an array')
+      .add(buildName, '\
+        lodash.invokeMap(numbers, "toFixed", 1)'
+      )
+      .add(otherName, '\
+        _.invokeMap(numbers, "toFixed", 1)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.invokeMap` with a function for `path` iterating an array')
+      .add(buildName, '\
+        lodash.invokeMap(numbers, Number.prototype.toFixed, 1)'
+      )
+      .add(otherName, '\
+        _.invokeMap(numbers, Number.prototype.toFixed, 1)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.invokeMap` iterating an object')
+      .add(buildName, '\
+        lodash.invokeMap(object, "toFixed", 1)'
+      )
+      .add(otherName, '\
+        _.invokeMap(object, "toFixed", 1)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.isEqual` comparing primitives')
+      .add(buildName, {
+        'fn': '\
+          lodash.isEqual(1, "1");\
+          lodash.isEqual(1, 1)',
+        'teardown': 'function isEqual(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.isEqual(1, "1");\
+          _.isEqual(1, 1);',
+        'teardown': 'function isEqual(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.isEqual` comparing primitives and their object counterparts (edge case)')
+      .add(buildName, {
+        'fn': '\
+          lodash.isEqual(objectOfPrimitives, objectOfObjects);\
+          lodash.isEqual(objectOfPrimitives, objectOfObjects2)',
+        'teardown': 'function isEqual(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.isEqual(objectOfPrimitives, objectOfObjects);\
+          _.isEqual(objectOfPrimitives, objectOfObjects2)',
+        'teardown': 'function isEqual(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.isEqual` comparing arrays')
+      .add(buildName, {
+        'fn': '\
+          lodash.isEqual(numbers, numbers2);\
+          lodash.isEqual(numbers2, numbers3)',
+        'teardown': 'function isEqual(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.isEqual(numbers, numbers2);\
+          _.isEqual(numbers2, numbers3)',
+        'teardown': 'function isEqual(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.isEqual` comparing nested arrays')
+      .add(buildName, {
+        'fn': '\
+          lodash.isEqual(nestedNumbers, nestedNumbers2);\
+          lodash.isEqual(nestedNumbers2, nestedNumbers3)',
+        'teardown': 'function isEqual(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.isEqual(nestedNumbers, nestedNumbers2);\
+          _.isEqual(nestedNumbers2, nestedNumbers3)',
+        'teardown': 'function isEqual(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.isEqual` comparing arrays of objects')
+      .add(buildName, {
+        'fn': '\
+          lodash.isEqual(objects, objects2);\
+          lodash.isEqual(objects2, objects3)',
+        'teardown': 'function isEqual(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.isEqual(objects, objects2);\
+          _.isEqual(objects2, objects3)',
+        'teardown': 'function isEqual(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.isEqual` comparing objects')
+      .add(buildName, {
+        'fn': '\
+          lodash.isEqual(object, object2);\
+          lodash.isEqual(object2, object3)',
+        'teardown': 'function isEqual(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.isEqual(object, object2);\
+          _.isEqual(object2, object3)',
+        'teardown': 'function isEqual(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.isArguments`, `_.isDate`, `_.isFunction`, `_.isNumber`, `_.isObject`, `_.isRegExp`')
+      .add(buildName, '\
+        lodash.isArguments(arguments);\
+        lodash.isArguments(object);\
+        lodash.isDate(date);\
+        lodash.isDate(object);\
+        lodash.isFunction(lodash);\
+        lodash.isFunction(object);\
+        lodash.isNumber(1);\
+        lodash.isNumber(object);\
+        lodash.isObject(object);\
+        lodash.isObject(1);\
+        lodash.isRegExp(regexp);\
+        lodash.isRegExp(object)'
+      )
+      .add(otherName, '\
+        _.isArguments(arguments);\
+        _.isArguments(object);\
+        _.isDate(date);\
+        _.isDate(object);\
+        _.isFunction(_);\
+        _.isFunction(object);\
+        _.isNumber(1);\
+        _.isNumber(object);\
+        _.isObject(object);\
+        _.isObject(1);\
+        _.isRegExp(regexp);\
+        _.isRegExp(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.keys` (uses native `Object.keys` if available)')
+      .add(buildName, '\
+        lodash.keys(object)'
+      )
+      .add(otherName, '\
+        _.keys(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.lastIndexOf`')
+      .add(buildName, {
+        'fn': 'lodash.lastIndexOf(hundredSortedValues, 0)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.lastIndexOf(hundredSortedValues, 0)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.map` iterating an array')
+      .add(buildName, '\
+        lodash.map(objects, function(value) {\
+          return value.num;\
+        })'
+      )
+      .add(otherName, '\
+        _.map(objects, function(value) {\
+          return value.num;\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.map` iterating an object')
+      .add(buildName, '\
+        lodash.map(object, function(value) {\
+          return value;\
+        })'
+      )
+      .add(otherName, '\
+        _.map(object, function(value) {\
+          return value;\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.map` with `_.property` shorthand')
+      .add(buildName, '\
+        lodash.map(objects, "num")'
+      )
+      .add(otherName, '\
+        _.map(objects, "num")'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.max`')
+      .add(buildName, '\
+        lodash.max(numbers)'
+      )
+      .add(otherName, '\
+        _.max(numbers)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.min`')
+      .add(buildName, '\
+        lodash.min(numbers)'
+      )
+      .add(otherName, '\
+        _.min(numbers)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.omit` iterating 20 properties, omitting 2 keys')
+      .add(buildName, '\
+        lodash.omit(object, "key6", "key13")'
+      )
+      .add(otherName, '\
+        _.omit(object, "key6", "key13")'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.omit` iterating 40 properties, omitting 20 keys')
+      .add(buildName, {
+        'fn': 'lodash.omit(wordToNumber, words)',
+        'teardown': 'function omit(){}'
+      })
+      .add(otherName, {
+        'fn': '_.omit(wordToNumber, words)',
+        'teardown': 'function omit(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.partial` (slow path)')
+      .add(buildName, {
+        'fn': 'lodash.partial(function(greeting) { return greeting + " " + this.name; }, "hi")',
+        'teardown': 'function partial(){}'
+      })
+      .add(otherName, {
+        'fn': '_.partial(function(greeting) { return greeting + " " + this.name; }, "hi")',
+        'teardown': 'function partial(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('partially applied call with arguments')
+      .add(buildName, {
+        'fn': 'lodashPartial("!")',
+        'teardown': 'function partial(){}'
+      })
+      .add(otherName, {
+        'fn': '_partial("!")',
+        'teardown': 'function partial(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.partition` iterating an array')
+      .add(buildName, '\
+        lodash.partition(numbers, function(num) {\
+          return num % 2;\
+        })'
+      )
+      .add(otherName, '\
+        _.partition(numbers, function(num) {\
+          return num % 2;\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.partition` iterating an object')
+      .add(buildName, '\
+        lodash.partition(object, function(num) {\
+          return num % 2;\
+        })'
+      )
+      .add(otherName, '\
+        _.partition(object, function(num) {\
+          return num % 2;\
+        })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.pick`')
+      .add(buildName, '\
+        lodash.pick(object, "key6", "key13")'
+      )
+      .add(otherName, '\
+        _.pick(object, "key6", "key13")'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.reduce` iterating an array')
+      .add(buildName, '\
+        lodash.reduce(numbers, function(result, value, index) {\
+          result[index] = value;\
+          return result;\
+        }, {})'
+      )
+      .add(otherName, '\
+        _.reduce(numbers, function(result, value, index) {\
+          result[index] = value;\
+          return result;\
+        }, {})'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.reduce` iterating an object')
+      .add(buildName, '\
+        lodash.reduce(object, function(result, value, key) {\
+          result.push(key, value);\
+          return result;\
+        }, [])'
+      )
+      .add(otherName, '\
+        _.reduce(object, function(result, value, key) {\
+          result.push(key, value);\
+          return result;\
+        }, [])'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.reduceRight` iterating an array')
+      .add(buildName, '\
+        lodash.reduceRight(numbers, function(result, value, index) {\
+          result[index] = value;\
+          return result;\
+        }, {})'
+      )
+      .add(otherName, '\
+        _.reduceRight(numbers, function(result, value, index) {\
+          result[index] = value;\
+          return result;\
+        }, {})'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.reduceRight` iterating an object')
+      .add(buildName, '\
+        lodash.reduceRight(object, function(result, value, key) {\
+          result.push(key, value);\
+          return result;\
+        }, [])'
+      )
+      .add(otherName, '\
+        _.reduceRight(object, function(result, value, key) {\
+          result.push(key, value);\
+          return result;\
+        }, [])'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.reject` iterating an array')
+      .add(buildName, '\
+        lodash.reject(numbers, function(num) {\
+          return num % 2;\
+        })'
+      )
+      .add(otherName, '\
+        _.reject(numbers, function(num) {\
+          return num % 2;\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.reject` iterating an object')
+      .add(buildName, '\
+        lodash.reject(object, function(num) {\
+          return num % 2;\
+        })'
+      )
+      .add(otherName, '\
+        _.reject(object, function(num) {\
+          return num % 2;\
+        })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sampleSize`')
+      .add(buildName, '\
+        lodash.sampleSize(numbers, limit / 2)'
+      )
+      .add(otherName, '\
+        _.sampleSize(numbers, limit / 2)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.shuffle`')
+      .add(buildName, '\
+        lodash.shuffle(numbers)'
+      )
+      .add(otherName, '\
+        _.shuffle(numbers)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.size` with an object')
+      .add(buildName, '\
+        lodash.size(object)'
+      )
+      .add(otherName, '\
+        _.size(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.some` iterating an array')
+      .add(buildName, '\
+        lodash.some(numbers, function(num) {\
+          return num == (limit - 1);\
+        })'
+      )
+      .add(otherName, '\
+        _.some(numbers, function(num) {\
+          return num == (limit - 1);\
+        })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.some` iterating an object')
+      .add(buildName, '\
+        lodash.some(object, function(num) {\
+          return num == (limit - 1);\
+        })'
+      )
+      .add(otherName, '\
+        _.some(object, function(num) {\
+          return num == (limit - 1);\
+        })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sortBy` with `callback`')
+      .add(buildName, '\
+        lodash.sortBy(numbers, function(num) { return Math.sin(num); })'
+      )
+      .add(otherName, '\
+        _.sortBy(numbers, function(num) { return Math.sin(num); })'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.sortBy` with `property` name')
+      .add(buildName, {
+        'fn': 'lodash.sortBy(words, "length")',
+        'teardown': 'function countBy(){}'
+      })
+      .add(otherName, {
+        'fn': '_.sortBy(words, "length")',
+        'teardown': 'function countBy(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sortedIndex`')
+      .add(buildName, '\
+        lodash.sortedIndex(numbers, limit)'
+      )
+      .add(otherName, '\
+        _.sortedIndex(numbers, limit)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sortedIndexBy`')
+      .add(buildName, {
+        'fn': '\
+          lodash.sortedIndexBy(words, "twenty-five", function(value) {\
+            return wordToNumber[value];\
+          })',
+        'teardown': 'function countBy(){}'
+      })
+      .add(otherName, {
+        'fn': '\
+          _.sortedIndexBy(words, "twenty-five", function(value) {\
+            return wordToNumber[value];\
+          })',
+        'teardown': 'function countBy(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sortedIndexOf`')
+      .add(buildName, {
+        'fn': 'lodash.sortedIndexOf(hundredSortedValues, 99)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.sortedIndexOf(hundredSortedValues, 99)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sortedLastIndexOf`')
+      .add(buildName, {
+        'fn': 'lodash.sortedLastIndexOf(hundredSortedValues, 0)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.sortedLastIndexOf(hundredSortedValues, 0)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.sum`')
+      .add(buildName, '\
+        lodash.sum(numbers)'
+      )
+      .add(otherName, '\
+        _.sum(numbers)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.template` (slow path)')
+      .add(buildName, {
+        'fn': 'lodash.template(tpl)(tplData)',
+        'teardown': 'function template(){}'
+      })
+      .add(otherName, {
+        'fn': '_.template(tpl)(tplData)',
+        'teardown': 'function template(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('compiled template')
+      .add(buildName, {
+        'fn': 'lodashTpl(tplData)',
+        'teardown': 'function template(){}'
+      })
+      .add(otherName, {
+        'fn': '_tpl(tplData)',
+        'teardown': 'function template(){}'
+      })
+  );
+
+  suites.push(
+    Benchmark.Suite('compiled template without a with-statement')
+      .add(buildName, {
+        'fn': 'lodashTplVerbose(tplData)',
+        'teardown': 'function template(){}'
+      })
+      .add(otherName, {
+        'fn': '_tplVerbose(tplData)',
+        'teardown': 'function template(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.times`')
+      .add(buildName, '\
+        var result = [];\
+        lodash.times(limit, function(n) { result.push(n); })'
+      )
+      .add(otherName, '\
+        var result = [];\
+        _.times(limit, function(n) { result.push(n); })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.toArray` with an array (edge case)')
+      .add(buildName, '\
+        lodash.toArray(numbers)'
+      )
+      .add(otherName, '\
+        _.toArray(numbers)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.toArray` with an object')
+      .add(buildName, '\
+        lodash.toArray(object)'
+      )
+      .add(otherName, '\
+        _.toArray(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.toPairs`')
+      .add(buildName, '\
+        lodash.toPairs(object)'
+      )
+      .add(otherName, '\
+        _.toPairs(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.unescape` string without html entities')
+      .add(buildName, '\
+        lodash.unescape("`&`, `<`, `>`, `\\"`, and `\'`")'
+      )
+      .add(otherName, '\
+        _.unescape("`&`, `<`, `>`, `\\"`, and `\'`")'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.unescape` string with html entities')
+      .add(buildName, '\
+        lodash.unescape("`&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;`")'
+      )
+      .add(otherName, '\
+        _.unescape("`&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;`")'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.union`')
+      .add(buildName, '\
+        lodash.union(numbers, twoNumbers, fourNumbers)'
+      )
+      .add(otherName, '\
+        _.union(numbers, twoNumbers, fourNumbers)'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.union` iterating an array of 200 elements')
+      .add(buildName, {
+        'fn': 'lodash.union(hundredValues, hundredValues2)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.union(hundredValues, hundredValues2)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.uniq`')
+      .add(buildName, '\
+        lodash.uniq(numbers.concat(twoNumbers, fourNumbers))'
+      )
+      .add(otherName, '\
+        _.uniq(numbers.concat(twoNumbers, fourNumbers))'
+      )
+  );
+
+  suites.push(
+    Benchmark.Suite('`_.uniq` iterating an array of 200 elements')
+      .add(buildName, {
+        'fn': 'lodash.uniq(twoHundredValues)',
+        'teardown': 'function multiArrays(){}'
+      })
+      .add(otherName, {
+        'fn': '_.uniq(twoHundredValues)',
+        'teardown': 'function multiArrays(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.uniqBy`')
+      .add(buildName, '\
+        lodash.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
+          return num % 2;\
+        })'
+      )
+      .add(otherName, '\
+        _.uniqBy(numbers.concat(twoNumbers, fourNumbers), function(num) {\
+          return num % 2;\
+        })'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.values`')
+      .add(buildName, '\
+        lodash.values(object)'
+      )
+      .add(otherName, '\
+        _.values(object)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.without`')
+      .add(buildName, '\
+        lodash.without(numbers, 9, 12, 14, 15)'
+      )
+      .add(otherName, '\
+        _.without(numbers, 9, 12, 14, 15)'
+      )
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.wrap` result called')
+      .add(buildName, {
+        'fn': 'lodashWrapped(2, 5)',
+        'teardown': 'function wrap(){}'
+      })
+      .add(otherName, {
+        'fn': '_wrapped(2, 5)',
+        'teardown': 'function wrap(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  suites.push(
+    Benchmark.Suite('`_.zip`')
+      .add(buildName, {
+        'fn': 'lodash.zip.apply(lodash, unzipped)',
+        'teardown': 'function zip(){}'
+      })
+      .add(otherName, {
+        'fn': '_.zip.apply(_, unzipped)',
+        'teardown': 'function zip(){}'
+      })
+  );
+
+  /*--------------------------------------------------------------------------*/
+
+  if (Benchmark.platform + '') {
+    log(Benchmark.platform);
+  }
+  // Expose `run` to be called later when executing in a browser.
+  if (document) {
+    root.run = run;
+  } else {
+    run();
+  }
+}.call(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/asset/test-ui.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/asset/test-ui.js
new file mode 100644
index 0000000..24f087a
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/asset/test-ui.js
@@ -0,0 +1,170 @@
+;(function(window) {
+  'use strict';
+
+  /** The base path of the lodash builds. */
+  var basePath = '../';
+
+  /** The lodash build to load. */
+  var build = (build = /build=([^&]+)/.exec(location.search)) && decodeURIComponent(build[1]);
+
+  /** The module loader to use. */
+  var loader = (loader = /loader=([^&]+)/.exec(location.search)) && decodeURIComponent(loader[1]);
+
+  /** The `ui` object. */
+  var ui = {};
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Registers an event listener on an element.
+   *
+   * @private
+   * @param {Element} element The element.
+   * @param {string} eventName The name of the event.
+   * @param {Function} handler The event handler.
+   * @returns {Element} The element.
+   */
+  function addListener(element, eventName, handler) {
+    if (typeof element.addEventListener != 'undefined') {
+      element.addEventListener(eventName, handler, false);
+    } else if (typeof element.attachEvent != 'undefined') {
+      element.attachEvent('on' + eventName, handler);
+    }
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // Initialize controls.
+  addListener(window, 'load', function() {
+    function eventHandler(event) {
+      var buildIndex = buildList.selectedIndex,
+          loaderIndex = loaderList.selectedIndex,
+          search = location.search.replace(/^\?|&?(?:build|loader)=[^&]*&?/g, '');
+
+      if (event.stopPropagation) {
+        event.stopPropagation();
+      } else {
+        event.cancelBubble = true;
+      }
+      location.href =
+        location.href.split('?')[0] + '?' +
+        (search ? search + '&' : '') +
+        'build=' + (buildIndex < 0 ? build : buildList[buildIndex].value) + '&' +
+        'loader=' + (loaderIndex < 0 ? loader : loaderList[loaderIndex].value);
+    }
+
+    function init() {
+      var toolbar = document.getElementById('qunit-testrunner-toolbar');
+      if (!toolbar) {
+        setTimeout(init, 15);
+        return;
+      }
+      toolbar.appendChild(span1);
+      toolbar.appendChild(span2);
+
+      buildList.selectedIndex = (function() {
+        switch (build) {
+          case 'lodash':            return 1;
+          case 'lodash-core-dev':   return 2;
+          case 'lodash-core':       return 3;
+          case 'lodash-dev':
+          case null:                return 0;
+        }
+        return -1;
+      }());
+
+      loaderList.selectedIndex = (function() {
+        switch (loader) {
+          case 'curl':      return 1;
+          case 'dojo':      return 2;
+          case 'requirejs': return 3;
+          case 'none':
+          case null:        return 0;
+        }
+        return -1;
+      }());
+
+      addListener(buildList, 'change', eventHandler);
+      addListener(loaderList, 'change', eventHandler);
+    }
+
+    var span1 = document.createElement('span');
+    span1.style.cssText = 'float:right';
+    span1.innerHTML =
+      '<label for="qunit-build">Build: </label>' +
+      '<select id="qunit-build">' +
+      '<option value="lodash-dev">lodash (development)</option>' +
+      '<option value="lodash">lodash (production)</option>' +
+      '<option value="lodash-core-dev">lodash-core (development)</option>' +
+      '<option value="lodash-core">lodash-core (production)</option>' +
+      '</select>';
+
+    var span2 = document.createElement('span');
+    span2.style.cssText = 'float:right';
+    span2.innerHTML =
+      '<label for="qunit-loader">Loader: </label>' +
+      '<select id="qunit-loader">' +
+      '<option value="none">None</option>' +
+      '<option value="curl">Curl</option>' +
+      '<option value="dojo">Dojo</option>' +
+      '<option value="requirejs">RequireJS</option>' +
+      '</select>';
+
+    var buildList = span1.lastChild,
+        loaderList = span2.lastChild;
+
+    setTimeout(function() {
+      ui.timing.loadEventEnd = +new Date;
+    }, 1);
+
+    init();
+  });
+
+  // The lodash build file path.
+  ui.buildPath = (function() {
+    var result;
+    switch (build) {
+      case 'lodash':            result = 'dist/lodash.min.js'; break;
+      case 'lodash-core-dev':   result = 'dist/lodash.core.js'; break;
+      case 'lodash-core':       result = 'dist/lodash.core.min.js'; break;
+      case null:                build  = 'lodash-dev';
+      case 'lodash-dev':        result = 'lodash.js'; break;
+      default:                  return build;
+    }
+    return basePath + result;
+  }());
+
+  // The module loader file path.
+  ui.loaderPath = (function() {
+    var result;
+    switch (loader) {
+      case 'curl':      result = 'node_modules/curl-amd/dist/curl-kitchen-sink/curl.js'; break;
+      case 'dojo':      result = 'node_modules/dojo/dojo.js'; break;
+      case 'requirejs': result = 'node_modules/requirejs/require.js'; break;
+      case null:        loader = 'none'; return '';
+      default:          return loader;
+    }
+    return basePath + result;
+  }());
+
+  // Used to indicate testing a core build.
+  ui.isCore = /\bcore(\.min)?\.js\b/.test(ui.buildPath);
+
+  // Used to indicate testing a foreign file.
+  ui.isForeign = RegExp('^(\\w+:)?//').test(build);
+
+  // Used to indicate testing a modularized build.
+  ui.isModularize = /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test([location.pathname, location.search]);
+
+  // Used to indicate testing in Sauce Labs' automated test cloud.
+  ui.isSauceLabs = location.port == '9001';
+
+  // Used to indicate that lodash is in strict mode.
+  ui.isStrict = /\bes\b/.test([location.pathname, location.search]);
+
+  ui.urlParams = { 'build': build, 'loader': loader };
+  ui.timing = { 'loadEventEnd': 0 };
+
+  window.ui = ui;
+
+}(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/asset/worker.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/asset/worker.js
new file mode 100644
index 0000000..8ccffa8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/asset/worker.js
@@ -0,0 +1,15 @@
+self.console || (self.console = { 'log': function() {} });
+
+addEventListener('message', function(e) {
+  if (e.data) {
+    try {
+      importScripts('../' + e.data);
+    } catch (e) {
+      var lineNumber = e.lineNumber,
+          message = (lineNumber == null ? '' : (lineNumber + ': ')) + e.message;
+
+      self._ = { 'VERSION': message };
+    }
+    postMessage(_.VERSION);
+  }
+}, false);
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/backbone.html b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/backbone.html
new file mode 100644
index 0000000..dd3df9f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/backbone.html
@@ -0,0 +1,170 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Backbone Test Suite</title>
+    <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
+  </head>
+  <body>
+    <script>
+      // Avoid reporting tests to Sauce Labs when script errors occur.
+      if (location.port == '9001') {
+        window.onerror = function(message) {
+          if (window.QUnit) {
+            QUnit.config.done.length = 0;
+          }
+          global_test_results = { 'message': message };
+        };
+      }
+    </script>
+    <script src="../node_modules/qunitjs/qunit/qunit.js"></script>
+    <script src="../node_modules/qunit-extras/qunit-extras.js"></script>
+    <script src="../vendor/json-js/json2.js"></script>
+    <script src="../node_modules/platform/platform.js"></script>
+    <script src="./asset/test-ui.js"></script>
+    <script src="../lodash.js"></script>
+    <script>
+      QUnit.config.asyncRetries = 10;
+      QUnit.config.hidepassed = true;
+
+      var mixinPrereqs = (function() {
+        var aliasToReal = {
+          'indexBy': 'keyBy',
+          'invoke': 'invokeMap'
+        };
+
+        var keyMap = {
+          'rest': 'tail'
+        };
+
+        var lodash = _.noConflict();
+
+        return function(_) {
+          lodash.defaultsDeep(_, { 'templateSettings': lodash.templateSettings });
+          lodash.mixin(_, lodash.pick(lodash, lodash.difference([
+            'countBy',
+            'debounce',
+            'difference',
+            'find',
+            'findIndex',
+            'findLastIndex',
+            'groupBy',
+            'includes',
+            'invert',
+            'invokeMap',
+            'keyBy',
+            'omit',
+            'partition',
+            'reduceRight',
+            'reject',
+            'sample',
+            'without'
+          ], lodash.functions(_))));
+
+          lodash.forOwn(keyMap, function(realName, otherName) {
+            _[otherName] = lodash[realName];
+            _.prototype[otherName] = lodash.prototype[realName];
+          });
+
+          lodash.forOwn(aliasToReal, function(realName, alias) {
+            _[alias] = _[realName];
+            _.prototype[alias] = _.prototype[realName];
+          });
+        };
+      }());
+
+      // Load prerequisite scripts.
+      document.write(ui.urlParams.loader == 'none'
+        ? '<script src="' + ui.buildPath + '"><\/script>'
+        : '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
+      );
+    </script>
+    <script>
+      if (ui.urlParams.loader == 'none') {
+        mixinPrereqs(_);
+        document.write([
+          '<script src="../node_modules/jquery/dist/jquery.js"><\/script>',
+          '<script src="../vendor/backbone/backbone.js"><\/script>',
+          '<script src="../vendor/backbone/test/setup/dom-setup.js"><\/script>',
+          '<script src="../vendor/backbone/test/setup/environment.js"><\/script>',
+          '<script src="../vendor/backbone/test/noconflict.js"><\/script>',
+          '<script src="../vendor/backbone/test/events.js"><\/script>',
+          '<script src="../vendor/backbone/test/model.js"><\/script>',
+          '<script src="../vendor/backbone/test/collection.js"><\/script>',
+          '<script src="../vendor/backbone/test/router.js"><\/script>',
+          '<script src="../vendor/backbone/test/view.js"><\/script>',
+          '<script src="../vendor/backbone/test/sync.js"><\/script>'
+        ].join('\n'));
+      }
+    </script>
+    <script>
+      (function() {
+        if (window.curl) {
+          curl.config({ 'apiName': 'require' });
+        }
+        if (!window.require) {
+          return;
+        }
+        var reBasename = /[\w.-]+$/,
+            basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
+            modulePath = ui.buildPath.replace(/\.js$/, ''),
+            locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''),
+            moduleMain = modulePath.match(reBasename)[0],
+            uid = +new Date;
+
+        function getConfig() {
+          var result = {
+            'baseUrl': './',
+            'urlArgs': 't=' + uid++,
+            'waitSeconds': 0,
+            'paths': {
+              'backbone': '../vendor/backbone/backbone',
+              'jquery': '../node_modules/jquery/dist/jquery'
+            },
+            'packages': [{
+              'name': 'test',
+              'location': '../vendor/backbone/test',
+              'config': {
+                // Work around no global being exported.
+                'exports': 'QUnit',
+                'loader': 'curl/loader/legacy'
+              }
+            }]
+          };
+
+          if (ui.isModularize) {
+            result.packages.push({
+              'name': 'underscore',
+              'location': locationPath,
+              'main': moduleMain
+            });
+          } else {
+            result.paths.underscore = modulePath;
+          }
+          return result;
+        }
+
+        QUnit.config.autostart = false;
+
+        require(getConfig(), ['underscore'], function(lodash) {
+          mixinPrereqs(lodash);
+          require(getConfig(), ['backbone'], function() {
+            require(getConfig(), [
+              'test/setup/dom-setup',
+              'test/setup/environment',
+              'test/noconflict',
+              'test/events',
+              'test/model',
+              'test/collection',
+              'test/router',
+              'test/view',
+              'test/sync'
+            ], function() {
+              QUnit.start();
+            });
+          });
+        });
+      }());
+    </script>
+  </body>
+</html>
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/fp.html b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/fp.html
new file mode 100644
index 0000000..7122966
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/fp.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>lodash-fp Test Suite</title>
+    <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
+  </head>
+  <body>
+    <script>
+      // Avoid reporting tests to Sauce Labs when script errors occur.
+      if (location.port == '9001') {
+        window.onerror = function(message) {
+          if (window.QUnit) {
+            QUnit.config.done.length = 0;
+          }
+          global_test_results = { 'message': message };
+        };
+      }
+    </script>
+    <script src="../lodash.js"></script>
+    <script src="../dist/lodash.fp.js"></script>
+    <script src="../dist/mapping.fp.js"></script>
+    <script src="../node_modules/qunitjs/qunit/qunit.js"></script>
+    <script src="../node_modules/qunit-extras/qunit-extras.js"></script>
+    <script src="../node_modules/platform/platform.js"></script>
+    <script src="./test-fp.js"></script>
+    <div id="qunit"></div>
+    <script>
+      // Set a more readable browser name.
+      window.onload = function() {
+        var timeoutId = setInterval(function() {
+          var ua = document.getElementById('qunit-userAgent');
+          if (ua) {
+            ua.innerHTML = platform;
+            clearInterval(timeoutId);
+          }
+        }, 16);
+      };
+    </script>
+  </body>
+</html>
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/index.html b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/index.html
new file mode 100644
index 0000000..aee3942
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/index.html
@@ -0,0 +1,351 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>lodash Test Suite</title>
+    <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
+    <style>
+      #exports, #module {
+        display: none;
+      }
+    </style>
+  </head>
+  <body>
+    <script>
+      // Avoid reporting tests to Sauce Labs when script errors occur.
+      if (location.port == '9001') {
+        window.onerror = function(message) {
+          if (window.QUnit) {
+            QUnit.config.done.length = 0;
+          }
+          global_test_results = { 'message': message };
+        };
+      }
+    </script>
+    <script src="../node_modules/lodash/lodash.js"></script>
+    <script>var lodashStable = _.noConflict();</script>
+    <script src="../node_modules/qunitjs/qunit/qunit.js"></script>
+    <script src="../node_modules/qunit-extras/qunit-extras.js"></script>
+    <script src="../node_modules/platform/platform.js"></script>
+    <script src="./asset/test-ui.js"></script>
+    <div id="qunit"></div>
+    <div id="exports"></div>
+    <div id="module"></div>
+    <script>
+      function setProperty(object, key, value) {
+        try {
+          Object.defineProperty(object, key, {
+            'configurable': true,
+            'enumerable': false,
+            'writable': true,
+            'value': value
+          });
+        } catch (e) {
+          object[key] = value;
+        }
+        return object;
+      }
+
+      function addBizarroMethods() {
+        var funcProto = Function.prototype,
+            objectProto = Object.prototype;
+
+        var hasOwnProperty = objectProto.hasOwnProperty,
+            fnToString = funcProto.toString,
+            nativeString = fnToString.call(objectProto.toString),
+            noop = function() {},
+            propertyIsEnumerable = objectProto.propertyIsEnumerable,
+            reToString = /toString/g;
+
+        function constant(value) {
+          return function() {
+            return value;
+          };
+        }
+
+        function createToString(funcName) {
+          return constant(nativeString.replace(reToString, funcName));
+        }
+
+        // Allow bypassing native checks.
+        setProperty(funcProto, 'toString', (function() {
+          function wrapper() {
+            setProperty(funcProto, 'toString', fnToString);
+            var result = hasOwnProperty.call(this, 'toString') ? this.toString() : fnToString.call(this);
+            setProperty(funcProto, 'toString', wrapper);
+            return result;
+          }
+          return wrapper;
+        }()));
+
+        // Add prototype extensions.
+        funcProto._method = noop;
+
+        // Set bad shims.
+        setProperty(Object, '_create', Object.create);
+        setProperty(Object, 'create', (function() {
+          function object() {}
+          return function(prototype) {
+            if (prototype === Object(prototype)) {
+              object.prototype = prototype;
+              var result = new object;
+              object.prototype = undefined;
+            }
+            return result || {};
+          };
+        }()));
+
+        setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols);
+        setProperty(Object, 'getOwnPropertySymbols', undefined);
+
+        setProperty(objectProto, '_propertyIsEnumerable', propertyIsEnumerable);
+        setProperty(objectProto, 'propertyIsEnumerable', function(key) {
+          return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
+        });
+
+        setProperty(window, '_Map', window.Map);
+        if (_Map) {
+          setProperty(window, 'Map', (function(Map) {
+            var count = 0;
+            return function() {
+              if (count++) {
+                return new Map;
+              }
+              var result = {};
+              setProperty(window, 'Map', Map);
+              return result;
+            };
+          }(_Map)));
+
+          setProperty(Map, 'toString', createToString('Map'));
+        }
+        setProperty(window, '_Promise', window.Promise);
+        setProperty(window, 'Promise', noop);
+
+        setProperty(window, '_Set', window.Set);
+        setProperty(window, 'Set', noop);
+
+        setProperty(window, '_Symbol', window.Symbol);
+        setProperty(window, 'Symbol', undefined);
+
+        setProperty(window, '_WeakMap', window.WeakMap);
+        setProperty(window, 'WeakMap', noop);
+
+        // Fake `WinRTError`.
+        setProperty(window, 'WinRTError', Error);
+
+        // Fake free variable `global`.
+        setProperty(window, 'exports', window);
+        setProperty(window, 'global', window);
+        setProperty(window, 'module', {});
+      }
+
+      function removeBizarroMethods() {
+        var funcProto = Function.prototype,
+            objectProto = Object.prototype;
+
+        setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable);
+
+        if (Object._create) {
+          Object.create = Object._create;
+        } else {
+          delete Object.create;
+        }
+        if (Object._getOwnPropertySymbols) {
+          Object.getOwnPropertySymbols = Object._getOwnPropertySymbols;
+        } else {
+          delete Object.getOwnPropertySymbols;
+        }
+        if (_Map) {
+          Map = _Map;
+        } else {
+          setProperty(window, 'Map', undefined);
+        }
+        if (_Promise) {
+          Promise = _Promise;
+        } else {
+          setProperty(window, 'Promise', undefined);
+        }
+        if (_Set) {
+          Set = _Set;
+        } else {
+          setProperty(window, 'Set', undefined);
+        }
+        if (_Symbol) {
+          Symbol = _Symbol;
+        }
+        if (_WeakMap) {
+          WeakMap = _WeakMap;
+        } else {
+          setProperty(window, 'WeakMap', undefined);
+        }
+        setProperty(window, '_Map', undefined);
+        setProperty(window, '_Promise', undefined);
+        setProperty(window, '_Set', undefined);
+        setProperty(window, '_Symbol', undefined);
+        setProperty(window, '_WeakMap', undefined);
+
+        setProperty(window, 'WinRTError', undefined);
+
+        setProperty(window, 'exports', document.getElementById('exports'));
+        setProperty(window, 'global', undefined);
+        setProperty(window, 'module', document.getElementById('module'));
+
+        delete funcProto._method;
+        delete Object._create;
+        delete Object._getOwnPropertySymbols;
+        delete objectProto._propertyIsEnumerable;
+      }
+
+      // Load lodash to expose it to the bad extensions/shims.
+      if (!ui.isModularize) {
+        addBizarroMethods();
+        document.write('<script src="' + ui.buildPath + '"><\/script>');
+      }
+    </script>
+    <script>
+      // Store lodash to test for bad extensions/shims.
+      if (!ui.isModularize) {
+        var lodashBizarro = window._;
+        window._ = undefined;
+        removeBizarroMethods();
+      }
+      // Load test scripts.
+      document.write((ui.isForeign || ui.urlParams.loader == 'none')
+        ? '<script src="' + ui.buildPath + '"><\/script><script src="test.js"><\/script>'
+        : '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
+      );
+    </script>
+    <script>
+      var lodashModule,
+          shimmedModule,
+          underscoreModule;
+
+      (function() {
+        if (window.curl) {
+          curl.config({ 'apiName': 'require' });
+        }
+        if (ui.isForeign || !window.require) {
+          return;
+        }
+        var reBasename = /[\w.-]+$/,
+            basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
+            modulePath = ui.buildPath.replace(/\.js$/, ''),
+            moduleMain = modulePath.match(reBasename)[0],
+            locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''),
+            shimmedLocationPath = './abc/../' + locationPath,
+            underscoreLocationPath = './xyz/../' + locationPath,
+            uid = +new Date;
+
+        function getConfig() {
+          var result = {
+            'baseUrl': './',
+            'urlArgs': 't=' + uid++,
+            'waitSeconds': 0,
+            'paths': {},
+            'packages': [{
+              'name': 'test',
+              'location': basePath + 'test',
+              'main': 'test',
+              'config': {
+                // Work around no global being exported.
+                'exports': 'QUnit',
+                'loader': 'curl/loader/legacy'
+              }
+            }],
+            'shim': {
+              'shimmed': {
+                'exports': '_'
+              }
+            }
+          };
+
+          if (ui.isModularize) {
+            result.packages.push({
+              'name': 'lodash',
+              'location': locationPath,
+              'main': moduleMain
+            }, {
+              'name': 'shimmed',
+              'location': shimmedLocationPath,
+              'main': moduleMain
+            }, {
+              'name': 'underscore',
+              'location': underscoreLocationPath,
+              'main': moduleMain
+            });
+          } else {
+            result.paths.lodash = modulePath;
+            result.paths.shimmed = shimmedLocationPath + '/' + moduleMain;
+            result.paths.underscore = underscoreLocationPath + '/' + moduleMain;
+          }
+          return result;
+        }
+
+        function loadTests() {
+          require(getConfig(), ['test'], function() {
+            QUnit.start();
+          });
+        }
+
+        function loadModulesAndTests() {
+          require(getConfig(), ['lodash', 'shimmed', 'underscore'], function(lodash, shimmed, underscore) {
+            lodashModule = lodash;
+            lodashModule.moduleName = 'lodash';
+
+            if (shimmed) {
+              shimmedModule = shimmed.result(shimmed, 'noConflict') || shimmed;
+              shimmedModule.moduleName = 'shimmed';
+            }
+            if (underscore) {
+              underscoreModule = underscore.result(underscore, 'noConflict') || underscore;
+              underscoreModule.moduleName = 'underscore';
+            }
+            window._ = lodash;
+
+            if (ui.isModularize) {
+              require(getConfig(), [
+                'lodash/_baseEach',
+                'lodash/_isIndex',
+                'lodash/_isIterateeCall'
+              ], function(baseEach, isIndex, isIterateeCall) {
+                lodash._baseEach = baseEach;
+                lodash._isIndex = isIndex;
+                lodash._isIterateeCall = isIterateeCall;
+                loadTests();
+              });
+            } else {
+              loadTests();
+            }
+          });
+        }
+
+        QUnit.config.autostart = false;
+
+        if (window.requirejs) {
+          addBizarroMethods();
+          require(getConfig(), ['lodash'], function(lodash) {
+            lodashBizarro = lodash.result(lodash, 'noConflict') || lodash;
+            delete requirejs.s.contexts._;
+
+            removeBizarroMethods();
+            loadModulesAndTests();
+          });
+        } else {
+          loadModulesAndTests();
+        }
+      }());
+
+      // Set a more readable browser name.
+      window.onload = function() {
+        var timeoutId = setInterval(function() {
+          var ua = document.getElementById('qunit-userAgent');
+          if (ua) {
+            ua.innerHTML = platform;
+            clearInterval(timeoutId);
+          }
+        }, 16);
+      };
+    </script>
+  </body>
+</html>
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/remove.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/remove.js
new file mode 100644
index 0000000..bd5aaf9
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/remove.js
@@ -0,0 +1,27 @@
+#!/usr/bin/env node
+'use strict';
+
+var _ = require('../lodash'),
+    fs = require('fs'),
+    path = require('path');
+
+var args = (args = process.argv)
+  .slice((args[0] === process.execPath || args[0] === 'node') ? 2 : 0);
+
+var filePath = path.resolve(args[1]),
+    reLine = /.*/gm;
+
+var pattern = (function() {
+  var result = args[0],
+      delimiter = result.charAt(0),
+      lastIndex = result.lastIndexOf(delimiter);
+
+  return RegExp(result.slice(1, lastIndex), result.slice(lastIndex + 1));
+}());
+
+/*----------------------------------------------------------------------------*/
+
+fs.writeFileSync(filePath, fs.readFileSync(filePath, 'utf8').replace(pattern, function(match) {
+  var snippet = _.slice(arguments, -3, -2)[0];
+  return match.replace(snippet, snippet.replace(reLine, ''));
+}));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/saucelabs.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/saucelabs.js
new file mode 100644
index 0000000..d10a313
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/saucelabs.js
@@ -0,0 +1,914 @@
+#!/usr/bin/env node
+'use strict';
+
+/** Environment shortcut. */
+var env = process.env;
+
+if (env.TRAVIS_SECURE_ENV_VARS == 'false') {
+  console.log('Skipping Sauce Labs jobs; secure environment variables are unavailable');
+  process.exit(0);
+}
+
+/** Load Node.js modules. */
+var EventEmitter = require('events').EventEmitter,
+    http = require('http'),
+    path = require('path'),
+    url = require('url'),
+    util = require('util');
+
+/** Load other modules. */
+var _ = require('../lodash.js'),
+    chalk = require('chalk'),
+    ecstatic = require('ecstatic'),
+    request = require('request'),
+    SauceTunnel = require('sauce-tunnel');
+
+/** Used for Sauce Labs credentials. */
+var accessKey = env.SAUCE_ACCESS_KEY,
+    username = env.SAUCE_USERNAME;
+
+/** Used as the default maximum number of times to retry a job and tunnel. */
+var maxJobRetries = 3,
+    maxTunnelRetries = 3;
+
+/** Used as the static file server middleware. */
+var mount = ecstatic({
+  'cache': 'no-cache',
+  'root': process.cwd()
+});
+
+/** Used as the list of ports supported by Sauce Connect. */
+var ports = [
+  80, 443, 888, 2000, 2001, 2020, 2109, 2222, 2310, 3000, 3001, 3030, 3210,
+  3333, 4000, 4001, 4040, 4321, 4502, 4503, 4567, 5000, 5001, 5050, 5555, 5432,
+  6000, 6001, 6060, 6666, 6543, 7000, 7070, 7774, 7777, 8000, 8001, 8003, 8031,
+  8080, 8081, 8765, 8777, 8888, 9000, 9001, 9080, 9090, 9876, 9877, 9999, 49221,
+  55001
+];
+
+/** Used by `logInline` to clear previously logged messages. */
+var prevLine = '';
+
+/** Method shortcut. */
+var push = Array.prototype.push;
+
+/** Used to detect error messages. */
+var reError = /(?:\be|E)rror\b/;
+
+/** Used to detect valid job ids. */
+var reJobId = /^[a-z0-9]{32}$/;
+
+/** Used to display the wait throbber. */
+var throbberDelay = 500,
+    waitCount = -1;
+
+/**
+ * Used as Sauce Labs config values.
+ * See the [Sauce Labs documentation](https://docs.saucelabs.com/reference/test-configuration/)
+ * for more details.
+ */
+var advisor = getOption('advisor', false),
+    build = getOption('build', (env.TRAVIS_COMMIT || '').slice(0, 10)),
+    commandTimeout = getOption('commandTimeout', 90),
+    compatMode = getOption('compatMode', null),
+    customData = Function('return {' + getOption('customData', '').replace(/^\{|}$/g, '') + '}')(),
+    deviceOrientation = getOption('deviceOrientation', 'portrait'),
+    framework = getOption('framework', 'qunit'),
+    idleTimeout = getOption('idleTimeout', 60),
+    jobName = getOption('name', 'unit tests'),
+    maxDuration = getOption('maxDuration', 180),
+    port = ports[Math.min(_.sortedIndex(ports, getOption('port', 9001)), ports.length - 1)],
+    publicAccess = getOption('public', true),
+    queueTimeout = getOption('queueTimeout', 240),
+    recordVideo = getOption('recordVideo', true),
+    recordScreenshots = getOption('recordScreenshots', false),
+    runner = getOption('runner', 'test/index.html').replace(/^\W+/, ''),
+    runnerUrl = getOption('runnerUrl', 'http://localhost:' + port + '/' + runner),
+    statusInterval = getOption('statusInterval', 5),
+    tags = getOption('tags', []),
+    throttled = getOption('throttled', 10),
+    tunneled = getOption('tunneled', true),
+    tunnelId = getOption('tunnelId', 'tunnel_' + (env.TRAVIS_JOB_ID || 0)),
+    tunnelTimeout = getOption('tunnelTimeout', 120),
+    videoUploadOnPass = getOption('videoUploadOnPass', false);
+
+/** Used to convert Sauce Labs browser identifiers to their formal names. */
+var browserNameMap = {
+  'googlechrome': 'Chrome',
+  'iehta': 'Internet Explorer',
+  'ipad': 'iPad',
+  'iphone': 'iPhone',
+  'microsoftedge': 'Edge'
+};
+
+/** List of platforms to load the runner on. */
+var platforms = [
+  ['Linux', 'android', '5.1'],
+  ['Windows 10', 'chrome', '49'],
+  ['Windows 10', 'chrome', '48'],
+  ['Windows 10', 'firefox', '45'],
+  ['Windows 10', 'firefox', '44'],
+  ['Windows 10', 'microsoftedge', '13'],
+  ['Windows 10', 'internet explorer', '11'],
+  ['Windows 8', 'internet explorer', '10'],
+  ['Windows 7', 'internet explorer', '9'],
+  // ['OS X 10.10', 'ipad', '9.1'],
+  ['OS X 10.11', 'safari', '9'],
+  ['OS X 10.10', 'safari', '8']
+];
+
+/** Used to tailor the `platforms` array. */
+var isAMD = _.includes(tags, 'amd'),
+    isBackbone = _.includes(tags, 'backbone'),
+    isModern = _.includes(tags, 'modern');
+
+// The platforms to test IE compatibility modes.
+if (compatMode) {
+  platforms = [
+    ['Windows 10', 'internet explorer', '11'],
+    ['Windows 8', 'internet explorer', '10'],
+    ['Windows 7', 'internet explorer', '9'],
+    ['Windows 7', 'internet explorer', '8']
+  ];
+}
+// The platforms for AMD tests.
+if (isAMD) {
+  platforms = _.filter(platforms, function(platform) {
+    var browser = browserName(platform[1]),
+        version = +platform[2];
+
+    switch (browser) {
+      case 'Android': return version >= 4.4;
+      case 'Opera': return version >= 10;
+    }
+    return true;
+  });
+}
+// The platforms for Backbone tests.
+if (isBackbone) {
+  platforms = _.filter(platforms, function(platform) {
+    var browser = browserName(platform[1]),
+        version = +platform[2];
+
+    switch (browser) {
+      case 'Firefox': return version >= 4;
+      case 'Internet Explorer': return version >= 7;
+      case 'iPad': return version >= 5;
+      case 'Opera': return version >= 12;
+    }
+    return true;
+  });
+}
+// The platforms for modern builds.
+if (isModern) {
+  platforms = _.filter(platforms, function(platform) {
+    var browser = browserName(platform[1]),
+        version = +platform[2];
+
+    switch (browser) {
+      case 'Android': return version >= 4.1;
+      case 'Firefox': return version >= 10;
+      case 'Internet Explorer': return version >= 9;
+      case 'iPad': return version >= 6;
+      case 'Opera': return version >= 12;
+      case 'Safari': return version >= 6;
+    }
+    return true;
+  });
+}
+
+/** Used as the default `Job` options object. */
+var jobOptions = {
+  'build': build,
+  'command-timeout': commandTimeout,
+  'custom-data': customData,
+  'device-orientation': deviceOrientation,
+  'framework': framework,
+  'idle-timeout': idleTimeout,
+  'max-duration': maxDuration,
+  'name': jobName,
+  'public': publicAccess,
+  'platforms': platforms,
+  'record-screenshots': recordScreenshots,
+  'record-video': recordVideo,
+  'sauce-advisor': advisor,
+  'tags': tags,
+  'url': runnerUrl,
+  'video-upload-on-pass': videoUploadOnPass
+};
+
+if (publicAccess === true) {
+  jobOptions['public'] = 'public';
+}
+if (tunneled) {
+  jobOptions['tunnel-identifier'] = tunnelId;
+}
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Resolves the formal browser name for a given Sauce Labs browser identifier.
+ *
+ * @private
+ * @param {string} identifier The browser identifier.
+ * @returns {string} Returns the formal browser name.
+ */
+function browserName(identifier) {
+  return browserNameMap[identifier] || _.startCase(identifier);
+}
+
+/**
+ * Gets the value for the given option name. If no value is available the
+ * `defaultValue` is returned.
+ *
+ * @private
+ * @param {string} name The name of the option.
+ * @param {*} defaultValue The default option value.
+ * @returns {*} Returns the option value.
+ */
+function getOption(name, defaultValue) {
+  var isArr = _.isArray(defaultValue);
+  return _.reduce(process.argv, function(result, value) {
+    if (isArr) {
+      value = optionToArray(name, value);
+      return _.isEmpty(value) ? result : value;
+    }
+    value = optionToValue(name, value);
+
+    return value == null ? result : value;
+  }, defaultValue);
+}
+
+/**
+ * Checks if `value` is a job ID.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a job ID, else `false`.
+ */
+function isJobId(value) {
+  return reJobId.test(value);
+}
+
+/**
+ * Writes an inline message to standard output.
+ *
+ * @private
+ * @param {string} [text=''] The text to log.
+ */
+function logInline(text) {
+  var blankLine = _.repeat(' ', _.size(prevLine));
+  prevLine = text = _.truncate(text, { 'length': 40 });
+  process.stdout.write(text + blankLine.slice(text.length) + '\r');
+}
+
+/**
+ * Writes the wait throbber to standard output.
+ *
+ * @private
+ */
+function logThrobber() {
+  logInline('Please wait' + _.repeat('.', (++waitCount % 3) + 1));
+}
+
+/**
+ * Converts a comma separated option value into an array.
+ *
+ * @private
+ * @param {string} name The name of the option to inspect.
+ * @param {string} string The options string.
+ * @returns {Array} Returns the new converted array.
+ */
+function optionToArray(name, string) {
+  return _.compact(_.invokeMap((optionToValue(name, string) || '').split(/, */), 'trim'));
+}
+
+/**
+ * Extracts the option value from an option string.
+ *
+ * @private
+ * @param {string} name The name of the option to inspect.
+ * @param {string} string The options string.
+ * @returns {string|undefined} Returns the option value, else `undefined`.
+ */
+function optionToValue(name, string) {
+  var result = string.match(RegExp('^' + name + '(?:=([\\s\\S]+))?$'));
+  if (result) {
+    result = _.result(result, 1);
+    result = result ? _.trim(result) : true;
+  }
+  if (result === 'false') {
+    return false;
+  }
+  return result || undefined;
+}
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * The `Job#remove` and `Tunnel#stop` callback used by `Jobs#restart`
+ * and `Tunnel#restart` respectively.
+ *
+ * @private
+ */
+function onGenericRestart() {
+  this.restarting = false;
+  this.emit('restart');
+  this.start();
+}
+
+/**
+ * The `request.put` and `SauceTunnel#stop` callback used by `Jobs#stop`
+ * and `Tunnel#stop` respectively.
+ *
+ * @private
+ * @param {Object} [error] The error object.
+ */
+function onGenericStop(error) {
+  this.running = this.stopping = false;
+  this.emit('stop', error);
+}
+
+/**
+ * The `request.del` callback used by `Jobs#remove`.
+ *
+ * @private
+ */
+function onJobRemove(error, res, body) {
+  this.id = this.taskId = this.url = null;
+  this.removing = false;
+  this.emit('remove');
+}
+
+/**
+ * The `Job#remove` callback used by `Jobs#reset`.
+ *
+ * @private
+ */
+function onJobReset() {
+  this.attempts = 0;
+  this.failed = this.resetting = false;
+  this._pollerId = this.id = this.result = this.taskId = this.url = null;
+  this.emit('reset');
+}
+
+/**
+ * The `request.post` callback used by `Jobs#start`.
+ *
+ * @private
+ * @param {Object} [error] The error object.
+ * @param {Object} res The response data object.
+ * @param {Object} body The response body JSON object.
+ */
+function onJobStart(error, res, body) {
+  this.starting = false;
+
+  if (this.stopping) {
+    return;
+  }
+  var statusCode = _.result(res, 'statusCode'),
+      taskId = _.first(_.result(body, 'js tests'));
+
+  if (error || !taskId || statusCode != 200) {
+    if (this.attempts < this.retries) {
+      this.restart();
+      return;
+    }
+    var na = 'unavailable',
+        bodyStr = _.isObject(body) ? '\n' + JSON.stringify(body) : na,
+        statusStr = _.isFinite(statusCode) ? statusCode : na;
+
+    logInline();
+    console.error('Failed to start job; status: %s, body: %s', statusStr, bodyStr);
+    if (error) {
+      console.error(error);
+    }
+    this.failed = true;
+    this.emit('complete');
+    return;
+  }
+  this.running = true;
+  this.taskId = taskId;
+  this.timestamp = _.now();
+  this.emit('start');
+  this.status();
+}
+
+/**
+ * The `request.post` callback used by `Job#status`.
+ *
+ * @private
+ * @param {Object} [error] The error object.
+ * @param {Object} res The response data object.
+ * @param {Object} body The response body JSON object.
+ */
+function onJobStatus(error, res, body) {
+  this.checking = false;
+
+  if (!this.running || this.stopping) {
+    return;
+  }
+  var completed = _.result(body, 'completed', false),
+      data = _.first(_.result(body, 'js tests')),
+      elapsed = (_.now() - this.timestamp) / 1000,
+      jobId = _.result(data, 'job_id', null),
+      jobResult = _.result(data, 'result', null),
+      jobStatus = _.result(data, 'status', ''),
+      jobUrl = _.result(data, 'url', null),
+      expired = (elapsed >= queueTimeout && !_.includes(jobStatus, 'in progress')),
+      options = this.options,
+      platform = options.platforms[0];
+
+  if (_.isObject(jobResult)) {
+    var message = _.result(jobResult, 'message');
+  } else {
+    if (typeof jobResult == 'string') {
+      message = jobResult;
+    }
+    jobResult = null;
+  }
+  if (isJobId(jobId)) {
+    this.id = jobId;
+    this.result = jobResult;
+    this.url = jobUrl;
+  } else {
+    completed = false;
+  }
+  this.emit('status', jobStatus);
+
+  if (!completed && !expired) {
+    this._pollerId = _.delay(_.bind(this.status, this), this.statusInterval * 1000);
+    return;
+  }
+  var description = browserName(platform[1]) + ' ' + platform[2] + ' on ' + _.startCase(platform[0]),
+      errored = !jobResult || !jobResult.passed || reError.test(message) || reError.test(jobStatus),
+      failures = _.result(jobResult, 'failed'),
+      label = options.name + ':',
+      tunnel = this.tunnel;
+
+  if (errored || failures) {
+    if (errored && this.attempts < this.retries) {
+      this.restart();
+      return;
+    }
+    var details = 'See ' + jobUrl + ' for details.';
+    this.failed = true;
+
+    logInline();
+    if (failures) {
+      console.error(label + ' %s ' + chalk.red('failed') + ' %d test' + (failures > 1 ? 's' : '') + '. %s', description, failures, details);
+    }
+    else if (tunnel.attempts < tunnel.retries) {
+      tunnel.restart();
+      return;
+    }
+    else {
+      if (typeof message == 'undefined') {
+        message = 'Results are unavailable. ' + details;
+      }
+      console.error(label, description, chalk.red('failed') + ';', message);
+    }
+  }
+  else {
+    logInline();
+    console.log(label, description, chalk.green('passed'));
+  }
+  this.running = false;
+  this.emit('complete');
+}
+
+/**
+ * The `SauceTunnel#start` callback used by `Tunnel#start`.
+ *
+ * @private
+ * @param {boolean} success The connection success indicator.
+ */
+function onTunnelStart(success) {
+  this.starting = false;
+
+  if (this._timeoutId) {
+    clearTimeout(this._timeoutId);
+    this._timeoutId = null;
+  }
+  if (!success) {
+    if (this.attempts < this.retries) {
+      this.restart();
+      return;
+    }
+    logInline();
+    console.error('Failed to open Sauce Connect tunnel');
+    process.exit(2);
+  }
+  logInline();
+  console.log('Sauce Connect tunnel opened');
+
+  var jobs = this.jobs;
+  push.apply(jobs.queue, jobs.all);
+
+  this.running = true;
+  this.emit('start');
+
+  console.log('Starting jobs...');
+  this.dequeue();
+}
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * The Job constructor.
+ *
+ * @private
+ * @param {Object} [properties] The properties to initialize a job with.
+ */
+function Job(properties) {
+  EventEmitter.call(this);
+
+  this.options = {};
+  _.merge(this, properties);
+  _.defaults(this.options, _.cloneDeep(jobOptions));
+
+  this.attempts = 0;
+  this.checking = this.failed = this.removing = this.resetting = this.restarting = this.running = this.starting = this.stopping = false;
+  this._pollerId = this.id = this.result = this.taskId = this.url = null;
+}
+
+util.inherits(Job, EventEmitter);
+
+/**
+ * Removes the job.
+ *
+ * @memberOf Job
+ * @param {Function} callback The function called once the job is removed.
+ * @param {Object} Returns the job instance.
+ */
+Job.prototype.remove = function(callback) {
+  this.once('remove', _.iteratee(callback));
+  if (this.removing) {
+    return this;
+  }
+  this.removing = true;
+  return this.stop(function() {
+    var onRemove = _.bind(onJobRemove, this);
+    if (!this.id) {
+      _.defer(onRemove);
+      return;
+    }
+    request.del(_.template('https://saucelabs.com/rest/v1/${user}/jobs/${id}')(this), {
+      'auth': { 'user': this.user, 'pass': this.pass }
+    }, onRemove);
+  });
+};
+
+/**
+ * Resets the job.
+ *
+ * @memberOf Job
+ * @param {Function} callback The function called once the job is reset.
+ * @param {Object} Returns the job instance.
+ */
+Job.prototype.reset = function(callback) {
+  this.once('reset', _.iteratee(callback));
+  if (this.resetting) {
+    return this;
+  }
+  this.resetting = true;
+  return this.remove(onJobReset);
+};
+
+/**
+ * Restarts the job.
+ *
+ * @memberOf Job
+ * @param {Function} callback The function called once the job is restarted.
+ * @param {Object} Returns the job instance.
+ */
+Job.prototype.restart = function(callback) {
+  this.once('restart', _.iteratee(callback));
+  if (this.restarting) {
+    return this;
+  }
+  this.restarting = true;
+
+  var options = this.options,
+      platform = options.platforms[0],
+      description = browserName(platform[1]) + ' ' + platform[2] + ' on ' + _.startCase(platform[0]),
+      label = options.name + ':';
+
+  logInline();
+  console.log('%s %s restart %d of %d', label, description, ++this.attempts, this.retries);
+
+  return this.remove(onGenericRestart);
+};
+
+/**
+ * Starts the job.
+ *
+ * @memberOf Job
+ * @param {Function} callback The function called once the job is started.
+ * @param {Object} Returns the job instance.
+ */
+Job.prototype.start = function(callback) {
+  this.once('start', _.iteratee(callback));
+  if (this.starting || this.running) {
+    return this;
+  }
+  this.starting = true;
+  request.post(_.template('https://saucelabs.com/rest/v1/${user}/js-tests')(this), {
+    'auth': { 'user': this.user, 'pass': this.pass },
+    'json': this.options
+  }, _.bind(onJobStart, this));
+
+  return this;
+};
+
+/**
+ * Checks the status of a job.
+ *
+ * @memberOf Job
+ * @param {Function} callback The function called once the status is resolved.
+ * @param {Object} Returns the job instance.
+ */
+Job.prototype.status = function(callback) {
+  this.once('status', _.iteratee(callback));
+  if (this.checking || this.removing || this.resetting || this.restarting || this.starting || this.stopping) {
+    return this;
+  }
+  this._pollerId = null;
+  this.checking = true;
+  request.post(_.template('https://saucelabs.com/rest/v1/${user}/js-tests/status')(this), {
+    'auth': { 'user': this.user, 'pass': this.pass },
+    'json': { 'js tests': [this.taskId] }
+  }, _.bind(onJobStatus, this));
+
+  return this;
+};
+
+/**
+ * Stops the job.
+ *
+ * @memberOf Job
+ * @param {Function} callback The function called once the job is stopped.
+ * @param {Object} Returns the job instance.
+ */
+Job.prototype.stop = function(callback) {
+  this.once('stop', _.iteratee(callback));
+  if (this.stopping) {
+    return this;
+  }
+  this.stopping = true;
+  if (this._pollerId) {
+    clearTimeout(this._pollerId);
+    this._pollerId = null;
+    this.checking = false;
+  }
+  var onStop = _.bind(onGenericStop, this);
+  if (!this.running || !this.id) {
+    _.defer(onStop);
+    return this;
+  }
+  request.put(_.template('https://saucelabs.com/rest/v1/${user}/jobs/${id}/stop')(this), {
+    'auth': { 'user': this.user, 'pass': this.pass }
+  }, onStop);
+
+  return this;
+};
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * The Tunnel constructor.
+ *
+ * @private
+ * @param {Object} [properties] The properties to initialize the tunnel with.
+ */
+function Tunnel(properties) {
+  EventEmitter.call(this);
+
+  _.merge(this, properties);
+
+  var active = [],
+      queue = [];
+
+  var all = _.map(this.platforms, _.bind(function(platform) {
+    return new Job(_.merge({
+      'user': this.user,
+      'pass': this.pass,
+      'tunnel': this,
+      'options': { 'platforms': [platform] }
+    }, this.job));
+  }, this));
+
+  var completed = 0,
+      restarted = [],
+      success = true,
+      total = all.length,
+      tunnel = this;
+
+  _.invokeMap(all, 'on', 'complete', function() {
+    _.pull(active, this);
+    if (success) {
+      success = !this.failed;
+    }
+    if (++completed == total) {
+      tunnel.stop(_.partial(tunnel.emit, 'complete', success));
+      return;
+    }
+    tunnel.dequeue();
+  });
+
+  _.invokeMap(all, 'on', 'restart', function() {
+    if (!_.includes(restarted, this)) {
+      restarted.push(this);
+    }
+    // Restart tunnel if all active jobs have restarted.
+    var threshold = Math.min(all.length, _.isFinite(throttled) ? throttled : 3);
+    if (tunnel.attempts < tunnel.retries &&
+        active.length >= threshold && _.isEmpty(_.difference(active, restarted))) {
+      tunnel.restart();
+    }
+  });
+
+  this.on('restart', function() {
+    completed = 0;
+    success = true;
+    restarted.length = 0;
+  });
+
+  this._timeoutId = null;
+  this.attempts = 0;
+  this.restarting = this.running = this.starting = this.stopping = false;
+  this.jobs = { 'active': active, 'all': all, 'queue': queue };
+  this.connection = new SauceTunnel(this.user, this.pass, this.id, this.tunneled, ['-P', '0']);
+}
+
+util.inherits(Tunnel, EventEmitter);
+
+/**
+ * Restarts the tunnel.
+ *
+ * @memberOf Tunnel
+ * @param {Function} callback The function called once the tunnel is restarted.
+ */
+Tunnel.prototype.restart = function(callback) {
+  this.once('restart', _.iteratee(callback));
+  if (this.restarting) {
+    return this;
+  }
+  this.restarting = true;
+
+  logInline();
+  console.log('Tunnel %s: restart %d of %d', this.id, ++this.attempts, this.retries);
+
+  var jobs = this.jobs,
+      active = jobs.active,
+      all = jobs.all;
+
+  var reset = _.after(all.length, _.bind(this.stop, this, onGenericRestart)),
+      stop = _.after(active.length, _.partial(_.invokeMap, all, 'reset', reset));
+
+  if (_.isEmpty(active)) {
+    _.defer(stop);
+  }
+  if (_.isEmpty(all)) {
+    _.defer(reset);
+  }
+  _.invokeMap(active, 'stop', function() {
+    _.pull(active, this);
+    stop();
+  });
+
+  if (this._timeoutId) {
+    clearTimeout(this._timeoutId);
+    this._timeoutId = null;
+  }
+  return this;
+};
+
+/**
+ * Starts the tunnel.
+ *
+ * @memberOf Tunnel
+ * @param {Function} callback The function called once the tunnel is started.
+ * @param {Object} Returns the tunnel instance.
+ */
+Tunnel.prototype.start = function(callback) {
+  this.once('start', _.iteratee(callback));
+  if (this.starting || this.running) {
+    return this;
+  }
+  this.starting = true;
+
+  logInline();
+  console.log('Opening Sauce Connect tunnel...');
+
+  var onStart = _.bind(onTunnelStart, this);
+  if (this.timeout) {
+    this._timeoutId = _.delay(onStart, this.timeout * 1000, false);
+  }
+  this.connection.start(onStart);
+  return this;
+};
+
+/**
+ * Removes jobs from the queue and starts them.
+ *
+ * @memberOf Tunnel
+ * @param {Object} Returns the tunnel instance.
+ */
+Tunnel.prototype.dequeue = function() {
+  var count = 0,
+      jobs = this.jobs,
+      active = jobs.active,
+      queue = jobs.queue,
+      throttled = this.throttled;
+
+  while (queue.length && (active.length < throttled)) {
+    var job = queue.shift();
+    active.push(job);
+    _.delay(_.bind(job.start, job), ++count * 1000);
+  }
+  return this;
+};
+
+/**
+ * Stops the tunnel.
+ *
+ * @memberOf Tunnel
+ * @param {Function} callback The function called once the tunnel is stopped.
+ * @param {Object} Returns the tunnel instance.
+ */
+Tunnel.prototype.stop = function(callback) {
+  this.once('stop', _.iteratee(callback));
+  if (this.stopping) {
+    return this;
+  }
+  this.stopping = true;
+
+  logInline();
+  console.log('Shutting down Sauce Connect tunnel...');
+
+  var jobs = this.jobs,
+      active = jobs.active;
+
+  var stop = _.after(active.length, _.bind(function() {
+    var onStop = _.bind(onGenericStop, this);
+    if (this.running) {
+      this.connection.stop(onStop);
+    } else {
+      onStop();
+    }
+  }, this));
+
+  jobs.queue.length = 0;
+  if (_.isEmpty(active)) {
+    _.defer(stop);
+  }
+  _.invokeMap(active, 'stop', function() {
+    _.pull(active, this);
+    stop();
+  });
+
+  if (this._timeoutId) {
+    clearTimeout(this._timeoutId);
+    this._timeoutId = null;
+  }
+  return this;
+};
+
+/*----------------------------------------------------------------------------*/
+
+// Cleanup any inline logs when exited via `ctrl+c`.
+process.on('SIGINT', function() {
+  logInline();
+  process.exit();
+});
+
+// Create a web server for the current working directory.
+http.createServer(function(req, res) {
+  // See http://msdn.microsoft.com/en-us/library/ff955275(v=vs.85).aspx.
+  if (compatMode && path.extname(url.parse(req.url).pathname) == '.html') {
+    res.setHeader('X-UA-Compatible', 'IE=' + compatMode);
+  }
+  mount(req, res);
+}).listen(port);
+
+// Setup Sauce Connect so we can use this server from Sauce Labs.
+var tunnel = new Tunnel({
+  'user': username,
+  'pass': accessKey,
+  'id': tunnelId,
+  'job': { 'retries': maxJobRetries, 'statusInterval': statusInterval },
+  'platforms': platforms,
+  'retries': maxTunnelRetries,
+  'throttled': throttled,
+  'tunneled': tunneled,
+  'timeout': tunnelTimeout
+});
+
+tunnel.on('complete', function(success) {
+  process.exit(success ? 0 : 1);
+});
+
+tunnel.start();
+
+setInterval(logThrobber, throbberDelay);
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/test-fp.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/test-fp.js
new file mode 100644
index 0000000..775d7ee
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/test-fp.js
@@ -0,0 +1,1769 @@
+;(function() {
+
+  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+  var undefined;
+
+  /** Used as the size to cover large array optimizations. */
+  var LARGE_ARRAY_SIZE = 200;
+
+  /** Used as a reference to the global object. */
+  var root = (typeof global == 'object' && global) || this;
+
+  /** Used for native method references. */
+  var arrayProto = Array.prototype;
+
+  /** Method and object shortcuts. */
+  var phantom = root.phantom,
+      amd = root.define && define.amd,
+      argv = root.process && process.argv,
+      document = !phantom && root.document,
+      noop = function() {},
+      slice = arrayProto.slice,
+      WeakMap = root.WeakMap;
+
+  // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
+  root.msWDfn = undefined;
+
+  /*--------------------------------------------------------------------------*/
+
+  /** Use a single "load" function. */
+  var load = (!amd && typeof require == 'function')
+    ? require
+    : noop;
+
+  /** The unit testing framework. */
+  var QUnit = root.QUnit || (root.QUnit = (
+    QUnit = load('../node_modules/qunitjs/qunit/qunit.js') || root.QUnit,
+    QUnit = QUnit.QUnit || QUnit
+  ));
+
+  /** Load stable Lodash and QUnit Extras. */
+  var _ = root._ || (root._ = (
+    _ = load('../lodash.js'),
+    _.runInContext(root)
+  ));
+
+  var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
+  if (QUnitExtras) {
+    QUnitExtras.runInContext(root);
+  }
+
+  var convert = (function() {
+    var baseConvert = root.fp || load('../fp/_baseConvert.js');
+    if (!root.fp) {
+      return function(name, func, options) {
+        return baseConvert(_, name, func, options);
+      };
+    }
+    return function(name, func, options) {
+      if (typeof name == 'function') {
+        options = func;
+        func = name;
+        name = undefined;
+      }
+      return name === undefined
+        ? baseConvert(func, options)
+        : baseConvert(_.runInContext(), options)[name];
+    };
+  }());
+
+  var allFalseOptions = {
+    'cap': false,
+    'curry': false,
+    'fixed': false,
+    'immutable': false,
+    'rearg': false
+  };
+
+  var fp = root.fp
+    ? (fp = _.noConflict(), _ = root._, fp)
+    : convert(_.runInContext());
+
+  var mapping = root.mapping || load('../fp/_mapping.js');
+
+  /*--------------------------------------------------------------------------*/
+
+  /**
+   * Skips a given number of tests with a passing result.
+   *
+   * @private
+   * @param {Object} assert The QUnit assert object.
+   * @param {number} [count=1] The number of tests to skip.
+   */
+  function skipAssert(assert, count) {
+    count || (count = 1);
+    while (count--) {
+      assert.ok(true, 'test skipped');
+    }
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  if (argv) {
+    console.log('Running lodash/fp tests.');
+  }
+
+  QUnit.module('convert module');
+
+  (function() {
+    QUnit.test('should work with `name` and `func`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4],
+          remove = convert('remove', _.remove);
+
+      var actual = remove(function(n) {
+        return n % 2 == 0;
+      })(array);
+
+      assert.deepEqual(array, [1, 2, 3, 4]);
+      assert.deepEqual(actual, [1, 3]);
+    });
+
+    QUnit.test('should work with `name`, `func`, and `options`', function(assert) {
+      assert.expect(3);
+
+      var array = [1, 2, 3, 4],
+          remove = convert('remove', _.remove, allFalseOptions);
+
+      var actual = remove(array, function(n, index) {
+        return index % 2 == 0;
+      });
+
+      assert.deepEqual(array, [2, 4]);
+      assert.deepEqual(actual, [1, 3]);
+      assert.deepEqual(remove(), []);
+    });
+
+    QUnit.test('should work with an object', function(assert) {
+      assert.expect(2);
+
+      if (!document) {
+        var array = [1, 2, 3, 4],
+            lodash = convert({ 'remove': _.remove });
+
+        var actual = lodash.remove(function(n) {
+          return n % 2 == 0;
+        })(array);
+
+        assert.deepEqual(array, [1, 2, 3, 4]);
+        assert.deepEqual(actual, [1, 3]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should work with an object and `options`', function(assert) {
+      assert.expect(3);
+
+      if (!document) {
+        var array = [1, 2, 3, 4],
+            lodash = convert({ 'remove': _.remove }, allFalseOptions);
+
+        var actual = lodash.remove(array, function(n, index) {
+          return index % 2 == 0;
+        });
+
+        assert.deepEqual(array, [2, 4]);
+        assert.deepEqual(actual, [1, 3]);
+        assert.deepEqual(lodash.remove(), []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should work with lodash and `options`', function(assert) {
+      assert.expect(3);
+
+      var array = [1, 2, 3, 4],
+          lodash = convert(_.runInContext(), allFalseOptions);
+
+      var actual = lodash.remove(array, function(n, index) {
+        return index % 2 == 0;
+      });
+
+      assert.deepEqual(array, [2, 4]);
+      assert.deepEqual(actual, [1, 3]);
+      assert.deepEqual(lodash.remove(), []);
+    });
+
+    QUnit.test('should work with `runInContext` and `options`', function(assert) {
+      assert.expect(3);
+
+      var array = [1, 2, 3, 4],
+          runInContext = convert('runInContext', _.runInContext, allFalseOptions),
+          lodash = runInContext();
+
+      var actual = lodash.remove(array, function(n, index) {
+        return index % 2 == 0;
+      });
+
+      assert.deepEqual(array, [2, 4]);
+      assert.deepEqual(actual, [1, 3]);
+      assert.deepEqual(lodash.remove(), []);
+    });
+
+    QUnit.test('should accept a variety of options', function(assert) {
+      assert.expect(8);
+
+      var array = [1, 2, 3, 4],
+          predicate = function(n) { return n % 2 == 0; },
+          value = _.clone(array),
+          remove = convert('remove', _.remove, { 'cap': false }),
+          actual = remove(function(n, index) { return index % 2 == 0; })(value);
+
+      assert.deepEqual(value, [1, 2, 3, 4]);
+      assert.deepEqual(actual, [2, 4]);
+
+      remove = convert('remove', _.remove, { 'curry': false });
+      actual = remove(predicate);
+
+      assert.deepEqual(actual, []);
+
+      var trim = convert('trim', _.trim, { 'fixed': false });
+      assert.strictEqual(trim('_-abc-_', '_-'), 'abc');
+
+      value = _.clone(array);
+      remove = convert('remove', _.remove, { 'immutable': false });
+      actual = remove(predicate)(value);
+
+      assert.deepEqual(value, [1, 3]);
+      assert.deepEqual(actual, [2, 4]);
+
+      value = _.clone(array);
+      remove = convert('remove', _.remove, { 'rearg': false });
+      actual = remove(value)(predicate);
+
+      assert.deepEqual(value, [1, 2, 3, 4]);
+      assert.deepEqual(actual, [1, 3]);
+    });
+
+    QUnit.test('should respect the `cap` option', function(assert) {
+      assert.expect(1);
+
+      var iteratee = convert('iteratee', _.iteratee, { 'cap': false });
+
+      var func = iteratee(function(a, b, c) {
+        return [a, b, c];
+      }, 3);
+
+      assert.deepEqual(func(1, 2, 3), [1, 2, 3]);
+    });
+
+    QUnit.test('should respect the `rearg` option', function(assert) {
+      assert.expect(1);
+
+      var add = convert('add', _.add, { 'rearg': true });
+
+      assert.strictEqual(add('2')('1'), '12');
+    });
+
+    QUnit.test('should only add a `placeholder` property if needed', function(assert) {
+      assert.expect(2);
+
+      if (!document) {
+        var methodNames = _.keys(mapping.placeholder),
+            expected = _.map(methodNames, _.constant(true));
+
+        var actual = _.map(methodNames, function(methodName) {
+          var object = {};
+          object[methodName] = _[methodName];
+
+          var lodash = convert(object);
+          return methodName in lodash;
+        });
+
+        assert.deepEqual(actual, expected);
+
+        var lodash = convert({ 'add': _.add });
+        assert.notOk('placeholder' in lodash);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('method.convert');
+
+  (function() {
+    QUnit.test('should exist on unconverted methods', function(assert) {
+      assert.expect(2);
+
+      var array = [],
+          isArray = fp.isArray.convert({ 'curry': true });
+
+      assert.strictEqual(fp.isArray(array), true);
+      assert.strictEqual(isArray()(array), true);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('convert methods');
+
+  _.each(['fp.convert', 'method.convert'], function(methodName) {
+    var isFp = methodName == 'fp.convert',
+        func = isFp ? fp.convert : fp.remove.convert;
+
+    QUnit.test('`' + methodName + '` should work with an object', function(assert) {
+      assert.expect(3);
+
+      var array = [1, 2, 3, 4],
+          lodash = func(allFalseOptions),
+          remove = isFp ? lodash.remove : lodash;
+
+      var actual = remove(array, function(n, index) {
+        return index % 2 == 0;
+      });
+
+      assert.deepEqual(array, [2, 4]);
+      assert.deepEqual(actual, [1, 3]);
+      assert.deepEqual(remove(), []);
+    });
+
+    QUnit.test('`' + methodName + '` should extend existing configs', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4],
+          lodash = func({ 'cap': false }),
+          remove = (isFp ? lodash.remove : lodash).convert({ 'rearg': false });
+
+      var actual = remove(array)(function(n, index) {
+        return index % 2 == 0;
+      });
+
+      assert.deepEqual(array, [1, 2, 3, 4]);
+      assert.deepEqual(actual, [2, 4]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('method arity checks');
+
+  (function() {
+    QUnit.test('should wrap methods with an arity > `1`', function(assert) {
+      assert.expect(1);
+
+      var methodNames = _.filter(_.functions(fp), function(methodName) {
+        return fp[methodName].length > 1;
+      });
+
+      assert.deepEqual(methodNames, []);
+    });
+
+    QUnit.test('should have >= arity of `aryMethod` designation', function(assert) {
+      assert.expect(4);
+
+      _.times(4, function(index) {
+        var aryCap = index + 1;
+
+        var methodNames = _.filter(mapping.aryMethod[aryCap], function(methodName) {
+          var key = _.result(mapping.remap, methodName, methodName),
+              arity = _[key].length;
+
+          return arity != 0 && arity < aryCap;
+        });
+
+        assert.deepEqual(methodNames, [], '`aryMethod[' + aryCap + ']`');
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('method aliases');
+
+  (function() {
+    QUnit.test('should have correct aliases', function(assert) {
+      assert.expect(1);
+
+      var actual = _.transform(mapping.aliasToReal, function(result, realName, alias) {
+        result.push([alias, fp[alias] === fp[realName]]);
+      }, []);
+
+      assert.deepEqual(_.reject(actual, 1), []);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('method ary caps');
+
+  (function() {
+    QUnit.test('should have a cap of 1', function(assert) {
+      assert.expect(1);
+
+      var funcMethods = [
+        'curry', 'iteratee', 'memoize', 'over', 'overEvery', 'overSome',
+        'method', 'methodOf', 'rest', 'runInContext'
+      ];
+
+      var exceptions = funcMethods.concat('mixin', 'template'),
+          expected = _.map(mapping.aryMethod[1], _.constant(true));
+
+      var actual = _.map(mapping.aryMethod[1], function(methodName) {
+        var arg = _.includes(funcMethods, methodName) ? _.noop : 1,
+            result = _.attempt(function() { return fp[methodName](arg); });
+
+        if (_.includes(exceptions, methodName)
+              ? typeof result == 'function'
+              : typeof result != 'function'
+            ) {
+          return true;
+        }
+        console.log(methodName, result);
+        return false;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should have a cap of 2', function(assert) {
+      assert.expect(1);
+
+      var funcMethods = [
+        'after', 'ary', 'before', 'bind', 'bindKey', 'curryN', 'debounce',
+        'delay', 'overArgs', 'partial', 'partialRight', 'rearg', 'throttle',
+        'wrap'
+      ];
+
+      var exceptions = _.difference(funcMethods.concat('matchesProperty'), ['cloneDeepWith', 'cloneWith', 'delay']),
+          expected = _.map(mapping.aryMethod[2], _.constant(true));
+
+      var actual = _.map(mapping.aryMethod[2], function(methodName) {
+        var args = _.includes(funcMethods, methodName) ? [methodName == 'curryN' ? 1 : _.noop, _.noop] : [1, []],
+            result = _.attempt(function() { return fp[methodName](args[0])(args[1]); });
+
+        if (_.includes(exceptions, methodName)
+              ? typeof result == 'function'
+              : typeof result != 'function'
+            ) {
+          return true;
+        }
+        console.log(methodName, result);
+        return false;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should have a cap of 3', function(assert) {
+      assert.expect(1);
+
+      var funcMethods = [
+        'assignWith', 'extendWith', 'isEqualWith', 'isMatchWith', 'reduce',
+        'reduceRight', 'transform', 'zipWith'
+      ];
+
+      var expected = _.map(mapping.aryMethod[3], _.constant(true));
+
+      var actual = _.map(mapping.aryMethod[3], function(methodName) {
+        var args = _.includes(funcMethods, methodName) ? [_.noop, 0, 1] : [0, 1, []],
+            result = _.attempt(function() { return fp[methodName](args[0])(args[1])(args[2]); });
+
+        if (typeof result != 'function') {
+          return true;
+        }
+        console.log(methodName, result);
+        return false;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('methods that use `indexOf`');
+
+  (function() {
+    QUnit.test('should work with `fp.indexOf`', function(assert) {
+      assert.expect(10);
+
+      var array = ['a', 'b', 'c'],
+          other = ['b', 'd', 'b'],
+          object = { 'a': 1, 'b': 2, 'c': 2 },
+          actual = fp.difference(array)(other);
+
+      assert.deepEqual(actual, ['a', 'c'], 'fp.difference');
+
+      actual = fp.includes('b')(array);
+      assert.strictEqual(actual, true, 'fp.includes');
+
+      actual = fp.intersection(other)(array);
+      assert.deepEqual(actual, ['b'], 'fp.intersection');
+
+      actual = fp.omit(other)(object);
+      assert.deepEqual(actual, { 'a': 1, 'c': 2 }, 'fp.omit');
+
+      actual = fp.union(other)(array);
+      assert.deepEqual(actual, ['a', 'b', 'c', 'd'], 'fp.union');
+
+      actual = fp.uniq(other);
+      assert.deepEqual(actual, ['b', 'd'], 'fp.uniq');
+
+      actual = fp.uniqBy(_.identity, other);
+      assert.deepEqual(actual, ['b', 'd'], 'fp.uniqBy');
+
+      actual = fp.without(array)(other);
+      assert.deepEqual(actual, ['a', 'c'], 'fp.without');
+
+      actual = fp.xor(other)(array);
+      assert.deepEqual(actual, ['a', 'c', 'd'], 'fp.xor');
+
+      actual = fp.pull('b')(array);
+      assert.deepEqual(actual, ['a', 'c'], 'fp.pull');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('cherry-picked methods');
+
+  (function() {
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(4);
+
+      var args,
+          array = [1, 2, 3],
+          object = { 'a': 1, 'b': 2 },
+          isFIFO = _.keys(object)[0] == 'a',
+          map = convert('map', _.map),
+          reduce = convert('reduce', _.reduce);
+
+      map(function() {
+        args || (args = slice.call(arguments));
+      })(array);
+
+      assert.deepEqual(args, [1]);
+
+      args = undefined;
+      map(function() {
+        args || (args = slice.call(arguments));
+      })(object);
+
+      assert.deepEqual(args, isFIFO ? [1] : [2]);
+
+      args = undefined;
+      reduce(function() {
+        args || (args = slice.call(arguments));
+      })(0)(array);
+
+      assert.deepEqual(args, [0, 1]);
+
+      args = undefined;
+      reduce(function() {
+        args || (args = slice.call(arguments));
+      })(0)(object);
+
+      assert.deepEqual(args, isFIFO ? [0, 1] : [0, 2]);
+    });
+
+    QUnit.test('should not support shortcut fusion', function(assert) {
+      assert.expect(3);
+
+      var array = fp.range(0, LARGE_ARRAY_SIZE),
+          filterCount = 0,
+          mapCount = 0;
+
+      var iteratee = function(value) {
+        mapCount++;
+        return value * value;
+      };
+
+      var predicate = function(value) {
+        filterCount++;
+        return value % 2 == 0;
+      };
+
+      var map1 = convert('map', _.map),
+          filter1 = convert('filter', _.filter),
+          take1 = convert('take', _.take);
+
+      var filter2 = filter1(predicate),
+          map2 = map1(iteratee),
+          take2 = take1(2);
+
+      var combined = fp.flow(map2, filter2, fp.compact, take2);
+
+      assert.deepEqual(combined(array), [4, 16]);
+      assert.strictEqual(filterCount, 200, 'filterCount');
+      assert.strictEqual(mapCount, 200, 'mapCount');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('iteratee shorthands');
+
+  (function() {
+    var objects = [{ 'a': 1, 'b': 2 }, { 'a': 3, 'b': 4 }];
+
+    QUnit.test('should work with "_.matches" shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.filter({ 'a': 3 })(objects), [objects[1]]);
+    });
+
+    QUnit.test('should work with "_.matchesProperty" shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.filter(['a', 3])(objects), [objects[1]]);
+    });
+
+    QUnit.test('should work with "_.property" shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.map('a')(objects), [1, 3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('mutation methods');
+
+  (function() {
+    var array = [1, 2, 3],
+        object = { 'a': 1 },
+        deepObject = { 'a': { 'b': 2, 'c': 3 } };
+
+    QUnit.test('should not mutate values', function(assert) {
+      assert.expect(42);
+
+      function Foo() {}
+      Foo.prototype = { 'b': 2 };
+
+      var value = _.clone(object),
+          actual = fp.assign(value)({ 'b': 2 });
+
+      assert.deepEqual(value, object, 'fp.assign');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assign');
+
+      value = _.clone(object);
+      actual = fp.assignWith(function(objValue, srcValue) {
+        return srcValue;
+      })(value)({ 'b': 2 });
+
+      assert.deepEqual(value, object, 'fp.assignWith');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignWith');
+
+      value = _.clone(object);
+      actual = fp.assignIn(value)(new Foo);
+
+      assert.deepEqual(value, object, 'fp.assignIn');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignIn');
+
+      value = _.clone(object);
+      actual = fp.assignInWith(function(objValue, srcValue) {
+        return srcValue;
+      })(value)(new Foo);
+
+      assert.deepEqual(value, object, 'fp.assignInWith');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignInWith');
+
+      value = _.clone(object);
+      actual = fp.defaults({ 'a': 2, 'b': 2 })(value);
+
+      assert.deepEqual(value, object, 'fp.defaults');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.defaults');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.defaultsDeep({ 'a': { 'c': 4, 'd': 4 } })(deepObject);
+
+      assert.deepEqual(value, { 'a': { 'b': 2, 'c': 3 } }, 'fp.defaultsDeep');
+      assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3, 'd': 4 } }, 'fp.defaultsDeep');
+
+      value = _.clone(object);
+      actual = fp.extend(value)(new Foo);
+
+      assert.deepEqual(value, object, 'fp.extend');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.extend');
+
+      value = _.clone(object);
+      actual = fp.extendWith(function(objValue, srcValue) {
+        return srcValue;
+      })(value)(new Foo);
+
+      assert.deepEqual(value, object, 'fp.extendWith');
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.extendWith');
+
+      value = _.clone(array);
+      actual = fp.fill(1)(2)('*')(value);
+
+      assert.deepEqual(value, array, 'fp.fill');
+      assert.deepEqual(actual, [1, '*', 3], 'fp.fill');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.merge(value)({ 'a': { 'd': 4 } });
+
+      assert.deepEqual(value, { 'a': { 'b': 2, 'c': 3 } }, 'fp.merge');
+      assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3, 'd': 4 } }, 'fp.merge');
+
+      value = _.cloneDeep(deepObject);
+      value.a.b = [1];
+
+      actual = fp.mergeWith(function(objValue, srcValue) {
+        if (_.isArray(objValue)) {
+          return objValue.concat(srcValue);
+        }
+      }, value, { 'a': { 'b': [2, 3] } });
+
+      assert.deepEqual(value, { 'a': { 'b': [1], 'c': 3 } }, 'fp.mergeWith');
+      assert.deepEqual(actual, { 'a': { 'b': [1, 2, 3], 'c': 3 } }, 'fp.mergeWith');
+
+      value = _.clone(array);
+      actual = fp.pull(2)(value);
+
+      assert.deepEqual(value, array, 'fp.pull');
+      assert.deepEqual(actual, [1, 3], 'fp.pull');
+
+      value = _.clone(array);
+      actual = fp.pullAll([1, 3])(value);
+
+      assert.deepEqual(value, array, 'fp.pullAll');
+      assert.deepEqual(actual, [2], 'fp.pullAll');
+
+      value = _.clone(array);
+      actual = fp.pullAt([0, 2])(value);
+
+      assert.deepEqual(value, array, 'fp.pullAt');
+      assert.deepEqual(actual, [2], 'fp.pullAt');
+
+      value = _.clone(array);
+      actual = fp.remove(function(value) {
+        return value === 2;
+      })(value);
+
+      assert.deepEqual(value, array, 'fp.remove');
+      assert.deepEqual(actual, [1, 3], 'fp.remove');
+
+      value = _.clone(array);
+      actual = fp.reverse(value);
+
+      assert.deepEqual(value, array, 'fp.reverse');
+      assert.deepEqual(actual, [3, 2, 1], 'fp.reverse');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.set('a.b')(3)(value);
+
+      assert.deepEqual(value, deepObject, 'fp.set');
+      assert.deepEqual(actual, { 'a': { 'b': 3, 'c': 3 } }, 'fp.set');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.setWith(Object)('d.e')(4)(value);
+
+      assert.deepEqual(value, deepObject, 'fp.setWith');
+      assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3 }, 'd': { 'e': 4 } }, 'fp.setWith');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.unset('a.b')(value);
+
+      assert.deepEqual(value, deepObject, 'fp.unset');
+      assert.deepEqual(actual, { 'a': { 'c': 3 } }, 'fp.unset');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.update('a.b')(function(n) { return n * n; })(value);
+
+      assert.deepEqual(value, deepObject, 'fp.update');
+      assert.deepEqual(actual, { 'a': { 'b': 4, 'c': 3 } }, 'fp.update');
+
+      value = _.cloneDeep(deepObject);
+      actual = fp.updateWith(Object)('d.e')(_.constant(4))(value);
+
+      assert.deepEqual(value, deepObject, 'fp.updateWith');
+      assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3 }, 'd': { 'e': 4 } }, 'fp.updateWith');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('placeholder methods');
+
+  (function() {
+    QUnit.test('should use `fp` as the default placeholder', function(assert) {
+      assert.expect(3);
+
+      var actual = fp.add(fp, 'b')('a');
+      assert.strictEqual(actual, 'ab');
+
+      actual = fp.slice(fp, 2)(1)(['a', 'b', 'c']);
+      assert.deepEqual(actual, ['b']);
+
+      actual = fp.fill(fp, 2)(1, '*')([1, 2, 3]);
+      assert.deepEqual(actual, [1, '*', 3]);
+    });
+
+    QUnit.test('should support `fp.placeholder`', function(assert) {
+      assert.expect(6);
+
+      _.each([[], fp.__], function(ph) {
+        fp.placeholder = ph;
+
+        var actual = fp.add(ph, 'b')('a');
+        assert.strictEqual(actual, 'ab');
+
+        actual = fp.slice(ph, 2)(1)(['a', 'b', 'c']);
+        assert.deepEqual(actual, ['b']);
+
+        actual = fp.fill(ph, 2)(1, '*')([1, 2, 3]);
+        assert.deepEqual(actual, [1, '*', 3]);
+      });
+    });
+
+    _.forOwn(mapping.placeholder, function(truthy, methodName) {
+      var func = fp[methodName];
+
+      QUnit.test('`_.' + methodName + '` should have a `placeholder` property', function(assert) {
+        assert.expect(2);
+
+        assert.ok(_.isObject(func.placeholder));
+        assert.strictEqual(func.placeholder, fp.__);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('set methods');
+
+  (function() {
+    QUnit.test('should only clone objects in `path`', function(assert) {
+      assert.expect(11);
+
+      var object = { 'a': { 'b': 2, 'c': 3 }, 'd': { 'e': 4 } },
+          value = _.cloneDeep(object),
+          actual = fp.set('a.b.c.d', 5, value);
+
+      assert.ok(_.isObject(actual.a.b), 'fp.set');
+      assert.ok(_.isNumber(actual.a.b), 'fp.set');
+
+      assert.strictEqual(actual.a.b.c.d, 5, 'fp.set');
+      assert.strictEqual(actual.d, value.d, 'fp.set');
+
+      value = _.cloneDeep(object);
+      actual = fp.setWith(Object)('[0][1]')('a')(value);
+
+      assert.deepEqual(actual[0], { '1': 'a' }, 'fp.setWith');
+
+      value = _.cloneDeep(object);
+      actual = fp.unset('a.b')(value);
+
+      assert.notOk('b' in actual.a, 'fp.unset');
+      assert.strictEqual(actual.a.c, value.a.c, 'fp.unset');
+
+      value = _.cloneDeep(object);
+      actual = fp.update('a.b')(function(n) { return n * n; })(value);
+
+      assert.strictEqual(actual.a.b, 4, 'fp.update');
+      assert.strictEqual(actual.d, value.d, 'fp.update');
+
+      value = _.cloneDeep(object);
+      actual = fp.updateWith(Object)('[0][1]')(_.constant('a'))(value);
+
+      assert.deepEqual(actual[0], { '1': 'a' }, 'fp.updateWith');
+      assert.strictEqual(actual.d, value.d, 'fp.updateWith');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('with methods');
+
+  (function() {
+    var object = { 'a': 1 };
+
+    QUnit.test('should provide the correct `customizer` arguments', function(assert) {
+      assert.expect(7);
+
+      var args,
+          value = _.clone(object);
+
+      fp.assignWith(function() {
+        args || (args = _.map(arguments, _.cloneDeep));
+      })(value)({ 'b': 2 });
+
+      assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }], 'fp.assignWith');
+
+      args = undefined;
+      value = _.clone(object);
+
+      fp.extendWith(function() {
+        args || (args = _.map(arguments, _.cloneDeep));
+      })(value)({ 'b': 2 });
+
+      assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }], 'fp.extendWith');
+
+      var iteration = 0,
+          objects = [{ 'a': 1 }, { 'a': 2 }],
+          stack = { '__data__': { 'array': [[objects[0], objects[1]]], 'map': null } },
+          expected = [1, 2, 'a', objects[0], objects[1], stack];
+
+      args = undefined;
+
+      fp.isEqualWith(function() {
+        if (++iteration == 2) {
+          args = _.map(arguments, _.cloneDeep);
+        }
+      })(objects[0])(objects[1]);
+
+      args[5] = _.omitBy(args[5], _.isFunction);
+      assert.deepEqual(args, expected, 'fp.isEqualWith');
+
+      args = undefined;
+      stack = { '__data__': { 'array': [], 'map': null } };
+      expected = [2, 1, 'a', objects[1], objects[0], stack];
+
+      fp.isMatchWith(function() {
+        args || (args = _.map(arguments, _.cloneDeep));
+      })(objects[0])(objects[1]);
+
+      args[5] = _.omitBy(args[5], _.isFunction);
+      assert.deepEqual(args, expected, 'fp.isMatchWith');
+
+      args = undefined;
+      value = { 'a': [1] };
+      expected = [[1], [2, 3], 'a', { 'a': [1] }, { 'a': [2, 3] }, stack];
+
+      fp.mergeWith(function() {
+        args || (args = _.map(arguments, _.cloneDeep));
+      })(value)({ 'a': [2, 3] });
+
+      args[5] = _.omitBy(args[5], _.isFunction);
+      assert.deepEqual(args, expected, 'fp.mergeWith');
+
+      args = undefined;
+      value = _.clone(object);
+
+      fp.setWith(function() {
+        args || (args = _.map(arguments, _.cloneDeep));
+      })('b.c')(2)(value);
+
+      assert.deepEqual(args, [undefined, 'b', { 'a': 1 }], 'fp.setWith');
+
+      args = undefined;
+      value = _.clone(object);
+
+      fp.updateWith(function() {
+        args || (args = _.map(arguments, _.cloneDeep));
+      })('b.c')(_.constant(2))(value);
+
+      assert.deepEqual(args, [undefined, 'b', { 'a': 1 }], 'fp.updateWith');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.add and fp.subtract');
+
+  _.each(['add', 'subtract'], function(methodName) {
+    var func = fp[methodName],
+        isAdd = methodName == 'add';
+
+    QUnit.test('`fp.' + methodName + '` should not have `rearg` applied', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func('1')('2'), isAdd ? '12' : -1);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.castArray');
+
+  (function() {
+    QUnit.test('should shallow clone array values', function(assert) {
+      assert.expect(2);
+
+      var array = [1],
+          actual = fp.castArray(array);
+
+      assert.deepEqual(actual, array);
+      assert.notStrictEqual(actual, array);
+    });
+
+    QUnit.test('should not shallow clone non-array values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1 },
+          actual = fp.castArray(object);
+
+      assert.deepEqual(actual, [object]);
+      assert.strictEqual(actual[0], object);
+    });
+
+    QUnit.test('should convert by name', function(assert) {
+      assert.expect(4);
+
+      var array = [1],
+          object = { 'a': 1 },
+          castArray = convert('castArray', _.castArray),
+          actual = castArray(array);
+
+      assert.deepEqual(actual, array);
+      assert.notStrictEqual(actual, array);
+
+      actual = castArray(object);
+      assert.deepEqual(actual, [object]);
+      assert.strictEqual(actual[0], object);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.curry and fp.curryRight');
+
+  _.each(['curry', 'curryRight'], function(methodName) {
+    var func = fp[methodName];
+
+    QUnit.test('`_.' + methodName + '` should only accept a `func` param', function(assert) {
+      assert.expect(1);
+
+      assert.raises(function() { func(1, _.noop); }, TypeError);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.curryN and fp.curryRightN');
+
+  _.each(['curryN', 'curryRightN'], function(methodName) {
+    var func = fp[methodName];
+
+    QUnit.test('`_.' + methodName + '` should accept an `arity` param', function(assert) {
+      assert.expect(1);
+
+      var actual = func(1)(function(a, b) { return [a, b]; })('a');
+      assert.deepEqual(actual, ['a', undefined]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.difference');
+
+  (function() {
+    QUnit.test('should return the elements of the first array not included in the second array', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.difference([1, 2])([2, 3]), [1]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.divide and fp.multiply');
+
+  _.each(['divide', 'multiply'], function(methodName) {
+    var func = fp[methodName],
+        isDivide = methodName == 'divide';
+
+    QUnit.test('`fp.' + methodName + '` should not have `rearg` applied', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func('2')('4'), isDivide ? 0.5 : 8);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.extend');
+
+  (function() {
+    QUnit.test('should convert by name', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype = { 'b': 2 };
+
+      var object = { 'a': 1 },
+          extend = convert('extend', _.extend),
+          value = _.clone(object),
+          actual = extend(value)(new Foo);
+
+      assert.deepEqual(value, object);
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.fill');
+
+  (function() {
+    QUnit.test('should have an argument order of `start`, `end`, then `value`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(fp.fill(1)(2)('*')(array), [1, '*', 3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.flatMapDepth');
+
+  (function() {
+    QUnit.test('should have an argument order of `iteratee`, `depth`, then `collection`', function(assert) {
+      assert.expect(2);
+
+      function duplicate(n) {
+        return [[[n, n]]];
+      }
+
+      var array = [1, 2],
+          object = { 'a': 1, 'b': 2 },
+          expected = [[1, 1], [2, 2]];
+
+      assert.deepEqual(fp.flatMapDepth(duplicate)(2)(array), expected);
+      assert.deepEqual(fp.flatMapDepth(duplicate)(2)(object), expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.flow and fp.flowRight');
+
+  _.each(['flow', 'flowRight'], function(methodName) {
+    var func = fp[methodName],
+        isFlow = methodName == 'flow';
+
+    QUnit.test('`fp.' + methodName + '` should support shortcut fusion', function(assert) {
+      assert.expect(6);
+
+      var filterCount,
+          mapCount,
+          array = fp.range(0, LARGE_ARRAY_SIZE);
+
+      var iteratee = function(value) {
+        mapCount++;
+        return value * value;
+      };
+
+      var predicate = function(value) {
+        filterCount++;
+        return value % 2 == 0;
+      };
+
+      var filter = fp.filter(predicate),
+          map = fp.map(iteratee),
+          take = fp.take(2);
+
+      _.times(2, function(index) {
+        var combined = isFlow
+          ? func(map, filter, fp.compact, take)
+          : func(take, fp.compact, filter, map);
+
+        filterCount = mapCount = 0;
+
+        if (WeakMap && WeakMap.name) {
+          assert.deepEqual(combined(array), [4, 16]);
+          assert.strictEqual(filterCount, 5, 'filterCount');
+          assert.strictEqual(mapCount, 5, 'mapCount');
+        }
+        else {
+          skipAssert(assert, 3);
+        }
+      });
+    });
+  });
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.getOr');
+
+  (function() {
+    QUnit.test('should accept a `defaultValue` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.getOr('default')('path')({});
+      assert.strictEqual(actual, 'default');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.gt and fp.gte');
+
+  _.each(['gt', 'gte'], function(methodName) {
+    var func = fp[methodName];
+
+    QUnit.test('`fp.' + methodName + '` should have `rearg` applied', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func(2)(1), true);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.inRange');
+
+  (function() {
+    QUnit.test('should have an argument order of `start`, `end`, then `value`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(fp.inRange(2)(4)(3), true);
+      assert.strictEqual(fp.inRange(-2)(-6)(-3), true);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.invoke');
+
+  (function() {
+    QUnit.test('should not accept an `args` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.invoke('toUpperCase')('a');
+      assert.strictEqual(actual, 'A');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.invokeMap');
+
+  (function() {
+    QUnit.test('should not accept an `args` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.invokeMap('toUpperCase')(['a', 'b']);
+      assert.deepEqual(actual, ['A', 'B']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.invokeArgs');
+
+  (function() {
+    QUnit.test('should accept an `args` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.invokeArgs('concat')(['b', 'c'])('a');
+      assert.strictEqual(actual, 'abc');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.invokeArgsMap');
+
+  (function() {
+    QUnit.test('should accept an `args` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.invokeArgsMap('concat')(['b', 'c'])(['a', 'A']);
+      assert.deepEqual(actual, ['abc', 'Abc']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.iteratee');
+
+  (function() {
+    QUnit.test('should return a iteratee with capped params', function(assert) {
+      assert.expect(1);
+
+      var func = fp.iteratee(function(a, b, c) { return [a, b, c]; }, 3);
+      assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]);
+    });
+
+    QUnit.test('should convert by name', function(assert) {
+      assert.expect(1);
+
+      var iteratee = convert('iteratee', _.iteratee),
+          func = iteratee(function(a, b, c) { return [a, b, c]; }, 3);
+
+      assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.lt and fp.lte');
+
+  _.each(['lt', 'lte'], function(methodName) {
+    var func = fp[methodName];
+
+    QUnit.test('`fp.' + methodName + '` should have `rearg` applied', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func(1)(2), true);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.mapKeys');
+
+  (function() {
+    QUnit.test('should only provide `key` to `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var args,
+          object = { 'a': 1 };
+
+      fp.mapKeys(function() {
+        args || (args = slice.call(arguments));
+      }, object);
+
+      assert.deepEqual(args, ['a']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.maxBy and fp.minBy');
+
+  _.each(['maxBy', 'minBy'], function(methodName) {
+    var array = [1, 2, 3],
+        func = fp[methodName],
+        isMax = methodName == 'maxBy';
+
+    QUnit.test('`fp.' + methodName + '` should work with an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var actual = func(function(num) {
+        return -num;
+      })(array);
+
+      assert.strictEqual(actual, isMax ? 1 : 3);
+    });
+
+    QUnit.test('`fp.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      func(function() {
+        args || (args = slice.call(arguments));
+      })(array);
+
+      assert.deepEqual(args, [1]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.mixin');
+
+  (function() {
+    var source = { 'a': _.noop };
+
+    QUnit.test('should mixin static methods but not prototype methods', function(assert) {
+      assert.expect(2);
+
+      fp.mixin(source);
+
+      assert.strictEqual(typeof fp.a, 'function');
+      assert.notOk('a' in fp.prototype);
+
+      delete fp.a;
+      delete fp.prototype.a;
+    });
+
+    QUnit.test('should not assign inherited `source` methods', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.a = _.noop;
+      fp.mixin(new Foo);
+
+      assert.notOk('a' in fp);
+      assert.notOk('a' in fp.prototype);
+
+      delete fp.a;
+      delete fp.prototype.a;
+    });
+
+    QUnit.test('should not remove existing prototype methods', function(assert) {
+      assert.expect(2);
+
+      var each1 = fp.each,
+          each2 = fp.prototype.each;
+
+      fp.mixin({ 'each': source.a });
+
+      assert.strictEqual(fp.each, source.a);
+      assert.strictEqual(fp.prototype.each, each2);
+
+      fp.each = each1;
+      fp.prototype.each = each2;
+    });
+
+    QUnit.test('should not export to the global when `source` is not an object', function(assert) {
+      assert.expect(2);
+
+      var props = _.without(_.keys(_), '_');
+
+      _.times(2, function(index) {
+        fp.mixin.apply(fp, index ? [1] : []);
+
+        assert.ok(_.every(props, function(key) {
+          return root[key] !== fp[key];
+        }));
+
+        _.each(props, function(key) {
+          if (root[key] === fp[key]) {
+            delete root[key];
+          }
+        });
+      });
+    });
+
+    QUnit.test('should convert by name', function(assert) {
+      assert.expect(3);
+
+      var object = { 'mixin': convert('mixin', _.mixin) };
+
+      function Foo() {}
+      Foo.mixin = object.mixin;
+      Foo.mixin(source);
+
+      assert.strictEqual(typeof Foo.a, 'function');
+      assert.notOk('a' in Foo.prototype);
+
+      object.mixin(source);
+      assert.strictEqual(typeof object.a, 'function');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.over');
+
+  (function() {
+    QUnit.test('should not cap iteratee args', function(assert) {
+      assert.expect(2);
+
+      _.each([fp.over, convert('over', _.over)], function(func) {
+        var over = func([Math.max, Math.min]);
+        assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.omitBy and fp.pickBy');
+
+  _.each(['omitBy', 'pickBy'], function(methodName) {
+    var func = fp[methodName];
+
+    QUnit.test('`fp.' + methodName + '` should provide `value` and `key` to `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var args,
+          object = { 'a': 1 };
+
+      func(function() {
+        args || (args = slice.call(arguments));
+      })(object);
+
+      assert.deepEqual(args, [1, 'a']);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('padChars methods');
+
+  _.each(['padChars', 'padCharsStart', 'padCharsEnd'], function(methodName) {
+    var func = fp[methodName],
+        isPad = methodName == 'padChars',
+        isStart = methodName == 'padCharsStart';
+
+    QUnit.test('`_.' + methodName + '` should truncate pad characters to fit the pad length', function(assert) {
+      assert.expect(1);
+
+      if (isPad) {
+        assert.strictEqual(func('_-')(8)('abc'), '_-abc_-_');
+      } else {
+        assert.strictEqual(func('_-')(6)('abc'), isStart ? '_-_abc' : 'abc_-_');
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.partial and fp.partialRight');
+
+  _.each(['partial', 'partialRight'], function(methodName) {
+    var func = fp[methodName],
+        isPartial = methodName == 'partial';
+
+    QUnit.test('`_.' + methodName + '` should accept an `args` param', function(assert) {
+      assert.expect(1);
+
+      var expected = isPartial ? [1, 2, 3] : [0, 1, 2];
+
+      var actual = func(function(a, b, c) {
+        return [a, b, c];
+      })([1, 2])(isPartial ? 3 : 0);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert by name', function(assert) {
+      assert.expect(2);
+
+      var expected = isPartial ? [1, 2, 3] : [0, 1, 2],
+          par = convert(methodName, _[methodName]),
+          ph = par.placeholder;
+
+      var actual = par(function(a, b, c) {
+        return [a, b, c];
+      })([1, 2])(isPartial ? 3 : 0);
+
+      assert.deepEqual(actual, expected);
+
+      actual = par(function(a, b, c) {
+        return [a, b, c];
+      })([ph, 2])(isPartial ? 1 : 0, isPartial ? 3 : 1);
+
+      assert.deepEqual(actual, expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.random');
+
+  (function() {
+    var array = Array(1000);
+
+    QUnit.test('should support a `min` and `max` argument', function(assert) {
+      assert.expect(1);
+
+      var min = 5,
+          max = 10;
+
+      assert.ok(_.some(array, function() {
+        var result = fp.random(min)(max);
+        return result >= min && result <= max;
+      }));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.range');
+
+  (function() {
+    QUnit.test('should have an argument order of `start` then `end`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.range(1)(4), [1, 2, 3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.reduce and fp.reduceRight');
+
+  _.each(['reduce', 'reduceRight'], function(methodName) {
+    var func = fp[methodName],
+        isReduce = methodName == 'reduce';
+
+    QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments when iterating an array', function(assert) {
+      assert.expect(1);
+
+      var args,
+          array = [1, 2, 3];
+
+      func(function() {
+        args || (args = slice.call(arguments));
+      })(0)(array);
+
+      assert.deepEqual(args, isReduce ? [0, 1] : [0, 3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments when iterating an object', function(assert) {
+      assert.expect(1);
+
+      var args,
+          object = { 'a': 1, 'b': 2 },
+          isFIFO = _.keys(object)[0] == 'a';
+
+      var expected = isFIFO
+        ? (isReduce ? [0, 1] : [0, 2])
+        : (isReduce ? [0, 2] : [0, 1]);
+
+      func(function() {
+        args || (args = slice.call(arguments));
+      })(0)(object);
+
+      assert.deepEqual(args, expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.restFrom');
+
+  (function() {
+    QUnit.test('should accept a `start` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.restFrom(2)(function() {
+        return slice.call(arguments);
+      })('a', 'b', 'c', 'd');
+
+      assert.deepEqual(actual, ['a', 'b', ['c', 'd']]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.runInContext');
+
+  (function() {
+    QUnit.test('should return a converted lodash instance', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(typeof fp.runInContext({}).curryN, 'function');
+    });
+
+    QUnit.test('should convert by name', function(assert) {
+      assert.expect(1);
+
+      var runInContext = convert('runInContext', _.runInContext);
+      assert.strictEqual(typeof runInContext({}).curryN, 'function');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.spreadFrom');
+
+  (function() {
+    QUnit.test('should accept a `start` param', function(assert) {
+      assert.expect(1);
+
+      var actual = fp.spreadFrom(2)(function() {
+        return slice.call(arguments);
+      })('a', 'b', ['c', 'd']);
+
+      assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('trimChars methods');
+
+  _.each(['trimChars', 'trimCharsStart', 'trimCharsEnd'], function(methodName, index) {
+    var func = fp[methodName],
+        parts = [];
+
+    if (index != 2) {
+      parts.push('leading');
+    }
+    if (index != 1) {
+      parts.push('trailing');
+    }
+    parts = parts.join(' and ');
+
+    QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
+      assert.expect(1);
+
+      var string = '-_-a-b-c-_-',
+          expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
+
+      assert.strictEqual(func('_-')(string), expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.uniqBy');
+
+  (function() {
+    var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
+
+    QUnit.test('should work with an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = objects.slice(0, 3);
+
+      var actual = fp.uniqBy(function(object) {
+        return object.a;
+      })(objects);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      fp.uniqBy(function() {
+        args || (args = slice.call(arguments));
+      })(objects);
+
+      assert.deepEqual(args, [objects[0]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.zip');
+
+  (function() {
+    QUnit.test('should zip together two arrays', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.zip([1, 2])([3, 4]), [[1, 3], [2, 4]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.zipObject');
+
+  (function() {
+    QUnit.test('should zip together key/value arrays into an object', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(fp.zipObject(['a', 'b'])([1, 2]), { 'a': 1, 'b': 2 });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('fp.zipWith');
+
+  (function() {
+    QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var array1 = [1, 2, 3],
+          array2 = [4, 5, 6];
+
+      var actual = fp.zipWith(function(a, b) {
+        return a + b;
+      })(array1)(array2);
+
+      assert.deepEqual(actual, [5, 7, 9]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.config.asyncRetries = 10;
+  QUnit.config.hidepassed = true;
+
+  if (!document) {
+    QUnit.config.noglobals = true;
+    QUnit.load();
+  }
+}.call(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/test.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/test.js
new file mode 100644
index 0000000..0df49ab
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/test.js
@@ -0,0 +1,26225 @@
+;(function() {
+
+  /** Used as a safe reference for `undefined` in pre-ES5 environments. */
+  var undefined;
+
+  /** Used to detect when a function becomes hot. */
+  var HOT_COUNT = 150;
+
+  /** Used as the size to cover large array optimizations. */
+  var LARGE_ARRAY_SIZE = 200;
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT = 'Expected a function';
+
+  /** Used as references for various `Number` constants. */
+  var MAX_SAFE_INTEGER = 9007199254740991,
+      MAX_INTEGER = 1.7976931348623157e+308;
+
+  /** Used as references for the maximum length and index of an array. */
+  var MAX_ARRAY_LENGTH = 4294967295,
+      MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1;
+
+  /** `Object#toString` result references. */
+  var funcTag = '[object Function]',
+      numberTag = '[object Number]',
+      objectTag = '[object Object]';
+
+  /** Used as a reference to the global object. */
+  var root = (typeof global == 'object' && global) || this;
+
+  /** Used to store lodash to test for bad extensions/shims. */
+  var lodashBizarro = root.lodashBizarro;
+
+  /** Used for native method references. */
+  var arrayProto = Array.prototype,
+      funcProto = Function.prototype,
+      objectProto = Object.prototype,
+      numberProto = Number.prototype,
+      stringProto = String.prototype;
+
+  /** Method and object shortcuts. */
+  var phantom = root.phantom,
+      process = root.process,
+      amd = root.define && define.amd,
+      argv = process && process.argv,
+      defineProperty = Object.defineProperty,
+      document = !phantom && root.document,
+      body = root.document && root.document.body,
+      create = Object.create,
+      fnToString = funcProto.toString,
+      freeze = Object.freeze,
+      getSymbols = Object.getOwnPropertySymbols,
+      identity = function(value) { return value; },
+      JSON = root.JSON,
+      noop = function() {},
+      objToString = objectProto.toString,
+      params = argv,
+      push = arrayProto.push,
+      realm = {},
+      slice = arrayProto.slice;
+
+  var ArrayBuffer = root.ArrayBuffer,
+      Buffer = root.Buffer,
+      Promise = root.Promise,
+      Map = root.Map,
+      Set = root.Set,
+      Symbol = root.Symbol,
+      Uint8Array = root.Uint8Array,
+      WeakMap = root.WeakMap,
+      WeakSet = root.WeakSet;
+
+  var arrayBuffer = ArrayBuffer ? new ArrayBuffer(2) : undefined,
+      map = Map ? new Map : undefined,
+      promise = Promise ? Promise.resolve(1) : undefined,
+      set = Set ? new Set : undefined,
+      symbol = Symbol ? Symbol('a') : undefined,
+      weakMap = WeakMap ? new WeakMap : undefined,
+      weakSet = WeakSet ? new WeakSet : undefined;
+
+  /** Math helpers. */
+  var add = function(x, y) { return x + y; },
+      doubled = function(n) { return n * 2; },
+      isEven = function(n) { return n % 2 == 0; },
+      square = function(n) { return n * n; };
+
+  /** Constant functions. */
+  var alwaysA = function() { return 'a'; },
+      alwaysB = function() { return 'b'; },
+      alwaysC = function() { return 'c'; };
+
+  var alwaysTrue = function() { return true; },
+      alwaysFalse = function() { return false; };
+
+  var alwaysNaN = function() { return NaN; },
+      alwaysNull = function() { return null; };
+
+  var alwaysZero = function() { return 0; },
+      alwaysOne = function() { return 1; },
+      alwaysTwo = function() { return 2; },
+      alwaysThree = function() { return 3; },
+      alwaysFour = function() { return 4; };
+
+  var alwaysEmptyArray = function() { return []; },
+      alwaysEmptyObject = function() { return {}; },
+      alwaysEmptyString = function() { return ''; };
+
+  /** List of latin-1 supplementary letters to basic latin letters. */
+  var burredLetters = [
+    '\xc0', '\xc1', '\xc2', '\xc3', '\xc4', '\xc5', '\xc6', '\xc7', '\xc8', '\xc9', '\xca', '\xcb', '\xcc', '\xcd', '\xce',
+    '\xcf', '\xd0', '\xd1', '\xd2', '\xd3', '\xd4', '\xd5', '\xd6', '\xd8', '\xd9', '\xda', '\xdb', '\xdc', '\xdd', '\xde',
+    '\xdf', '\xe0', '\xe1', '\xe2', '\xe3', '\xe4', '\xe5', '\xe6', '\xe7', '\xe8', '\xe9', '\xea', '\xeb', '\xec', '\xed', '\xee',
+    '\xef', '\xf0', '\xf1', '\xf2', '\xf3', '\xf4', '\xf5', '\xf6', '\xf8', '\xf9', '\xfa', '\xfb', '\xfc', '\xfd', '\xfe', '\xff'
+  ];
+
+  /** List of combining diacritical marks. */
+  var comboMarks = [
+    '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0305', '\u0306', '\u0307', '\u0308', '\u0309', '\u030a', '\u030b', '\u030c', '\u030d', '\u030e', '\u030f',
+    '\u0310', '\u0311', '\u0312', '\u0313', '\u0314', '\u0315', '\u0316', '\u0317', '\u0318', '\u0319', '\u031a', '\u031b', '\u031c', '\u031d', '\u031e', '\u031f',
+    '\u0320', '\u0321', '\u0322', '\u0323', '\u0324', '\u0325', '\u0326', '\u0327', '\u0328', '\u0329', '\u032a', '\u032b', '\u032c', '\u032d', '\u032e', '\u032f',
+    '\u0330', '\u0331', '\u0332', '\u0333', '\u0334', '\u0335', '\u0336', '\u0337', '\u0338', '\u0339', '\u033a', '\u033b', '\u033c', '\u033d', '\u033e', '\u033f',
+    '\u0340', '\u0341', '\u0342', '\u0343', '\u0344', '\u0345', '\u0346', '\u0347', '\u0348', '\u0349', '\u034a', '\u034b', '\u034c', '\u034d', '\u034e', '\u034f',
+    '\u0350', '\u0351', '\u0352', '\u0353', '\u0354', '\u0355', '\u0356', '\u0357', '\u0358', '\u0359', '\u035a', '\u035b', '\u035c', '\u035d', '\u035e', '\u035f',
+    '\u0360', '\u0361', '\u0362', '\u0363', '\u0364', '\u0365', '\u0366', '\u0367', '\u0368', '\u0369', '\u036a', '\u036b', '\u036c', '\u036d', '\u036e', '\u036f',
+    '\ufe20', '\ufe21', '\ufe22', '\ufe23'
+  ];
+
+  /** List of `burredLetters` translated to basic latin letters. */
+  var deburredLetters = [
+    'A',  'A', 'A', 'A', 'A', 'A', 'Ae', 'C',  'E', 'E', 'E', 'E', 'I', 'I', 'I',
+    'I',  'D', 'N', 'O', 'O', 'O', 'O',  'O',  'O', 'U', 'U', 'U', 'U', 'Y', 'Th',
+    'ss', 'a', 'a', 'a', 'a', 'a', 'a',  'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i',  'i',
+    'i',  'd', 'n', 'o', 'o', 'o', 'o',  'o',  'o', 'u', 'u', 'u', 'u', 'y', 'th', 'y'
+  ];
+
+  /** Used to provide falsey values to methods. */
+  var falsey = [, null, undefined, false, 0, NaN, ''];
+
+  /** Used to specify the emoji style glyph variant of characters. */
+  var emojiVar = '\ufe0f';
+
+  /** Used to provide empty values to methods. */
+  var empties = [[], {}].concat(falsey.slice(1));
+
+  /** Used to test error objects. */
+  var errors = [
+    new Error,
+    new EvalError,
+    new RangeError,
+    new ReferenceError,
+    new SyntaxError,
+    new TypeError,
+    new URIError
+  ];
+
+  /** List of fitzpatrick modifiers. */
+  var fitzModifiers = [
+    '\ud83c\udffb',
+    '\ud83c\udffc',
+    '\ud83c\udffd',
+    '\ud83c\udffe',
+    '\ud83c\udfff'
+  ];
+
+  /** Used to provide primitive values to methods. */
+  var primitives = [null, undefined, false, true, 1, NaN, 'a'];
+
+  /** Used to check whether methods support typed arrays. */
+  var typedArrays = [
+    'Float32Array',
+    'Float64Array',
+    'Int8Array',
+    'Int16Array',
+    'Int32Array',
+    'Uint8Array',
+    'Uint8ClampedArray',
+    'Uint16Array',
+    'Uint32Array'
+  ];
+
+  /** Used to check whether methods support array views. */
+  var arrayViews = typedArrays.concat('DataView');
+
+  /** The file path of the lodash file to test. */
+  var filePath = (function() {
+    var min = 2,
+        result = params || [];
+
+    if (phantom) {
+      min = 0;
+      result = params = phantom.args || require('system').args;
+    }
+    var last = result[result.length - 1];
+    result = (result.length > min && !/test(?:\.js)?$/.test(last)) ? last : '../lodash.js';
+
+    if (!amd) {
+      try {
+        result = require('fs').realpathSync(result);
+      } catch (e) {}
+
+      try {
+        result = require.resolve(result);
+      } catch (e) {}
+    }
+    return result;
+  }());
+
+  /** The `ui` object. */
+  var ui = root.ui || (root.ui = {
+    'buildPath': filePath,
+    'loaderPath': '',
+    'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath),
+    'isStrict': /\bes\b/.test(filePath),
+    'urlParams': {}
+  });
+
+  /** The basename of the lodash file to test. */
+  var basename = /[\w.-]+$/.exec(filePath)[0];
+
+  /** Used to indicate testing a modularized build. */
+  var isModularize = ui.isModularize;
+
+  /** Detect if testing `npm` modules. */
+  var isNpm = isModularize && /\bnpm\b/.test([ui.buildPath, ui.urlParams.build]);
+
+  /** Detect if running in PhantomJS. */
+  var isPhantom = phantom || (typeof callPhantom == 'function');
+
+  /** Detect if lodash is in strict mode. */
+  var isStrict = ui.isStrict;
+
+  /*--------------------------------------------------------------------------*/
+
+  // Leak to avoid sporadic `noglobals` fails on Edge in Sauce Labs.
+  root.msWDfn = undefined;
+
+  // Exit early if going to run tests in a PhantomJS web page.
+  if (phantom && isModularize) {
+    var page = require('webpage').create();
+
+    page.onCallback = function(details) {
+      var coverage = details.coverage;
+      if (coverage) {
+        var fs = require('fs'),
+            cwd = fs.workingDirectory,
+            sep = fs.separator;
+
+        fs.write([cwd, 'coverage', 'coverage.json'].join(sep), JSON.stringify(coverage));
+      }
+      phantom.exit(details.failed ? 1 : 0);
+    };
+
+    page.onConsoleMessage = function(message) {
+      console.log(message);
+    };
+
+    page.onInitialized = function() {
+      page.evaluate(function() {
+        document.addEventListener('DOMContentLoaded', function() {
+          QUnit.done(function(details) {
+            details.coverage = window.__coverage__;
+            callPhantom(details);
+          });
+        });
+      });
+    };
+
+    page.open(filePath, function(status) {
+      if (status != 'success') {
+        console.log('PhantomJS failed to load page: ' + filePath);
+        phantom.exit(1);
+      }
+    });
+
+    console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
+    return;
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  /** Used to test Web Workers. */
+  var Worker = !(ui.isForeign || ui.isSauceLabs || isModularize) &&
+    (document && document.origin != 'null') && root.Worker;
+
+  /** Used to test host objects in IE. */
+  try {
+    var xml = new ActiveXObject('Microsoft.XMLDOM');
+  } catch (e) {}
+
+  /** Poison the free variable `root` in Node.js */
+  try {
+    defineProperty(global.root, 'root', {
+      'configurable': false,
+      'enumerable': false,
+      'get': function() { throw new ReferenceError; }
+    });
+  } catch (e) {}
+
+  /** Use a single "load" function. */
+  var load = (!amd && typeof require == 'function')
+    ? require
+    : noop;
+
+  /** The unit testing framework. */
+  var QUnit = root.QUnit || (root.QUnit = load('../node_modules/qunitjs/qunit/qunit.js'));
+
+  /** Load stable Lodash and QUnit Extras. */
+  var lodashStable = root.lodashStable;
+  if (!lodashStable) {
+    try {
+      lodashStable = load('../node_modules/lodash/lodash.js');
+    } catch (e) {
+      console.log('Error: The stable lodash dev dependency should be at least a version behind master branch.');
+      return;
+    }
+    lodashStable = lodashStable.noConflict();
+  }
+  lodashStable = lodashStable.runInContext(root);
+
+  var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js');
+  if (QUnitExtras) {
+    QUnitExtras.runInContext(root);
+  }
+
+  /** The `lodash` function to test. */
+  var _ = root._ || (root._ = (
+    _ = load(filePath),
+    _ = _._ || (isStrict = ui.isStrict = isStrict || 'default' in _, _['default']) || _,
+    (_.runInContext ? _.runInContext(root) : _)
+  ));
+
+  /** Used to detect instrumented istanbul code coverage runs. */
+  var coverage = root.__coverage__ || root[lodashStable.findKey(root, function(value, key) {
+    return /^(?:\$\$cov_\d+\$\$)$/.test(key);
+  })];
+
+  /** Used to test generator functions. */
+  var generator = lodashStable.attempt(function() {
+    return Function('return function*(){}');
+  });
+
+  /** Used to restore the `_` reference. */
+  var oldDash = root._;
+
+  /**
+   * Used to check for problems removing whitespace. For a whitespace reference,
+   * see [V8's unit test](https://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/whitespaces.js).
+   */
+  var whitespace = lodashStable.filter([
+    // Basic whitespace characters.
+    ' ', '\t', '\x0b', '\f', '\xa0', '\ufeff',
+
+    // Line terminators.
+    '\n', '\r', '\u2028', '\u2029',
+
+    // Unicode category "Zs" space separators.
+    '\u1680', '\u180e', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',
+    '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u202f', '\u205f', '\u3000'
+  ],
+  function(chr) { return /\s/.exec(chr); })
+  .join('');
+
+  /**
+   * Creates a custom error object.
+   *
+   * @private
+   * @constructor
+   * @param {string} message The error message.
+   */
+  function CustomError(message) {
+    this.name = 'CustomError';
+    this.message = message;
+  }
+
+  CustomError.prototype = lodashStable.create(Error.prototype, {
+    'constructor': CustomError
+  });
+
+  /**
+   * Removes all own enumerable string keyed properties from a given object.
+   *
+   * @private
+   * @param {Object} object The object to empty.
+   */
+  function emptyObject(object) {
+    lodashStable.forOwn(object, function(value, key, object) {
+      delete object[key];
+    });
+  }
+
+  /**
+   * Extracts the unwrapped value from its wrapper.
+   *
+   * @private
+   * @param {Object} wrapper The wrapper to unwrap.
+   * @returns {*} Returns the unwrapped value.
+   */
+  function getUnwrappedValue(wrapper) {
+    var index = -1,
+        actions = wrapper.__actions__,
+        length = actions.length,
+        result = wrapper.__wrapped__;
+
+    while (++index < length) {
+      var args = [result],
+          action = actions[index];
+
+      push.apply(args, action.args);
+      result = action.func.apply(action.thisArg, args);
+    }
+    return result;
+  }
+
+  /**
+   * Sets a non-enumerable property value on `object`.
+   *
+   * Note: This function is used to avoid a bug in older versions of V8 where
+   * overwriting non-enumerable built-ins makes them enumerable.
+   * See https://code.google.com/p/v8/issues/detail?id=1623
+   *
+   * @private
+   * @param {Object} object The object modify.
+   * @param {string} key The name of the property to set.
+   * @param {*} value The property value.
+   */
+  function setProperty(object, key, value) {
+    try {
+      defineProperty(object, key, {
+        'configurable': true,
+        'enumerable': false,
+        'writable': true,
+        'value': value
+      });
+    } catch (e) {
+      object[key] = value;
+    }
+    return object;
+  }
+
+  /**
+   * Skips a given number of tests with a passing result.
+   *
+   * @private
+   * @param {Object} assert The QUnit assert object.
+   * @param {number} [count=1] The number of tests to skip.
+   */
+  function skipAssert(assert, count) {
+    count || (count = 1);
+    while (count--) {
+      assert.ok(true, 'test skipped');
+    }
+  }
+
+  /*--------------------------------------------------------------------------*/
+
+  // Add bizarro values.
+  (function() {
+    if (document || (typeof require != 'function')) {
+      return;
+    }
+    var nativeString = fnToString.call(toString),
+        reToString = /toString/g;
+
+    function createToString(funcName) {
+      return lodashStable.constant(nativeString.replace(reToString, funcName));
+    }
+
+    // Allow bypassing native checks.
+    setProperty(funcProto, 'toString', function wrapper() {
+      setProperty(funcProto, 'toString', fnToString);
+      var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this);
+      setProperty(funcProto, 'toString', wrapper);
+      return result;
+    });
+
+    // Add prototype extensions.
+    funcProto._method = noop;
+
+    // Set bad shims.
+    setProperty(Object, 'create', (function() {
+      function object() {}
+      return function(prototype) {
+        if (lodashStable.isObject(prototype)) {
+          object.prototype = prototype;
+          var result = new object;
+          object.prototype = undefined;
+        }
+        return result || {};
+      };
+    }()));
+
+    setProperty(Object, 'getOwnPropertySymbols', undefined);
+
+    var _propertyIsEnumerable = objectProto.propertyIsEnumerable;
+    setProperty(objectProto, 'propertyIsEnumerable', function(key) {
+      return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key);
+    });
+
+    if (Buffer) {
+      defineProperty(root, 'Buffer', {
+        'configurable': true,
+        'enumerable': true,
+        'get': function get() {
+          var caller = get.caller,
+              name = caller ? caller.name : '';
+
+          if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) {
+            return Buffer;
+          }
+        }
+      });
+    }
+    if (Map) {
+      setProperty(root, 'Map', (function() {
+        var count = 0;
+        return function() {
+          if (count++) {
+            return new Map;
+          }
+          setProperty(root, 'Map', Map);
+          return {};
+        };
+      }()));
+
+      setProperty(root.Map, 'toString', createToString('Map'));
+    }
+    setProperty(root, 'Promise', noop);
+    setProperty(root, 'Set', noop);
+    setProperty(root, 'Symbol', undefined);
+    setProperty(root, 'WeakMap', noop);
+
+    // Fake `WinRTError`.
+    setProperty(root, 'WinRTError', Error);
+
+    // Clear cache so lodash can be reloaded.
+    emptyObject(require.cache);
+
+    // Load lodash and expose it to the bad extensions/shims.
+    lodashBizarro = (lodashBizarro = require(filePath))._ || lodashBizarro['default'] || lodashBizarro;
+    root._ = oldDash;
+
+    // Restore built-in methods.
+    setProperty(Object, 'create', create);
+    setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable);
+    setProperty(root, 'Buffer', Buffer);
+
+    if (getSymbols) {
+      Object.getOwnPropertySymbols = getSymbols;
+    } else {
+      delete Object.getOwnPropertySymbols;
+    }
+    if (Map) {
+      setProperty(root, 'Map', Map);
+    } else {
+      delete root.Map;
+    }
+    if (Promise) {
+      setProperty(root, 'Promise', Promise);
+    } else {
+      delete root.Promise;
+    }
+    if (Set) {
+      setProperty(root, 'Set', Set);
+    } else {
+      delete root.Set;
+    }
+    if (Symbol) {
+      setProperty(root, 'Symbol', Symbol);
+    } else {
+      delete root.Symbol;
+    }
+    if (WeakMap) {
+      setProperty(root, 'WeakMap', WeakMap);
+    } else {
+      delete root.WeakMap;
+    }
+    delete root.WinRTError;
+    delete funcProto._method;
+  }());
+
+  // Add other realm values from the `vm` module.
+  lodashStable.attempt(function() {
+    lodashStable.assign(realm, require('vm').runInNewContext([
+      '(function() {',
+      '  var noop = function() {},',
+      '      root = this;',
+      '',
+      '  var object = {',
+      "    'ArrayBuffer': root.ArrayBuffer,",
+      "    'arguments': (function() { return arguments; }(1, 2, 3)),",
+      "    'array': [1],",
+      "    'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
+      "    'boolean': Object(false),",
+      "    'date': new Date,",
+      "    'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
+      "    'function': noop,",
+      "    'map': root.Map ? new root.Map : undefined,",
+      "    'nan': NaN,",
+      "    'null': null,",
+      "    'number': Object(0),",
+      "    'object': { 'a': 1 },",
+      "    'promise': root.Promise ? Promise.resolve(1) : undefined,",
+      "    'regexp': /x/,",
+      "    'set': root.Set ? new root.Set : undefined,",
+      "    'string': Object('a'),",
+      "    'symbol': root.Symbol ? root.Symbol() : undefined,",
+      "    'undefined': undefined,",
+      "    'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
+      "    'weakSet': root.WeakSet ? new root.WeakSet : undefined",
+      '  };',
+      '',
+      "  ['" + arrayViews.join("', '") + "'].forEach(function(type) {",
+      '    var Ctor = root[type]',
+      '    object[type] = Ctor;',
+      '    object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
+      '  });',
+      '',
+      '  return object;',
+      '}())'
+    ].join('\n')));
+  });
+
+  // Add other realm values from an iframe.
+  lodashStable.attempt(function() {
+    _._realm = realm;
+
+    var iframe = document.createElement('iframe');
+    iframe.frameBorder = iframe.height = iframe.width = 0;
+    body.appendChild(iframe);
+
+    var idoc = (idoc = iframe.contentDocument || iframe.contentWindow).document || idoc;
+    idoc.write([
+      '<script>',
+      'var _ = parent._;',
+      '',
+      '  var noop = function() {},',
+      '      root = this;',
+      '',
+      'var object = {',
+      "  'ArrayBuffer': root.ArrayBuffer,",
+      "  'arguments': (function() { return arguments; }(1, 2, 3)),",
+      "  'array': [1],",
+      "  'arrayBuffer': root.ArrayBuffer ? new root.ArrayBuffer : undefined,",
+      "  'boolean': Object(false),",
+      "  'date': new Date,",
+      "  'errors': [new Error, new EvalError, new RangeError, new ReferenceError, new SyntaxError, new TypeError, new URIError],",
+      "  'function': noop,",
+      "  'map': root.Map ? new root.Map : undefined,",
+      "  'nan': NaN,",
+      "  'null': null,",
+      "  'number': Object(0),",
+      "  'object': { 'a': 1 },",
+      "  'promise': root.Promise ? Promise.resolve(1) : undefined,",
+      "  'regexp': /x/,",
+      "  'set': root.Set ? new root.Set : undefined,",
+      "  'string': Object('a'),",
+      "  'symbol': root.Symbol ? root.Symbol() : undefined,",
+      "  'undefined': undefined,",
+      "  'weakMap': root.WeakMap ? new root.WeakMap : undefined,",
+      "  'weakSet': root.WeakSet ? new root.WeakSet : undefined",
+      '};',
+      '',
+      "_.each(['" + arrayViews.join("', '") + "'], function(type) {",
+      '  var Ctor = root[type];',
+      '  object[type] = Ctor;',
+      '  object[type.toLowerCase()] = Ctor ? new Ctor(new ArrayBuffer(24)) : undefined;',
+      '});',
+      '',
+      '_.assign(_._realm, object);',
+      '<\/script>'
+    ].join('\n'));
+
+    idoc.close();
+    delete _._realm;
+  });
+
+  // Add a web worker.
+  lodashStable.attempt(function() {
+    var worker = new Worker('./asset/worker.js?t=' + (+new Date));
+    worker.addEventListener('message', function(e) {
+      _._VERSION = e.data || '';
+    }, false);
+
+    worker.postMessage(ui.buildPath);
+  });
+
+  // Expose internal modules for better code coverage.
+  lodashStable.attempt(function() {
+    var path = require('path'),
+        basePath = path.dirname(filePath);
+
+    if (isModularize && !(amd || isNpm)) {
+      lodashStable.each([
+        '_baseEach',
+        '_isIndex',
+        '_isIterateeCall'
+      ], function(relPath) {
+        var func = require(path.join(basePath, relPath)),
+            funcName = path.basename(relPath);
+
+        _['_' + funcName] = func[funcName] || func['default'] || func;
+      });
+    }
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  if (params) {
+    console.log('Running lodash tests.');
+    console.log('test.js invoked with arguments: ' + JSON.stringify(slice.call(params)));
+  }
+
+  QUnit.module(basename);
+
+  (function() {
+    QUnit.test('should support loading ' + basename + ' as the "lodash" module', function(assert) {
+      assert.expect(1);
+
+      if (amd) {
+        assert.strictEqual((lodashModule || {}).moduleName, 'lodash');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should support loading ' + basename + ' with the Require.js "shim" configuration option', function(assert) {
+      assert.expect(1);
+
+      if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) {
+        assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed');
+      } else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should support loading ' + basename + ' as the "underscore" module', function(assert) {
+      assert.expect(1);
+
+      if (amd) {
+        assert.strictEqual((underscoreModule || {}).moduleName, 'underscore');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should support loading ' + basename + ' in a web worker', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      if (Worker) {
+        var limit = 30000 / QUnit.config.asyncRetries,
+            start = +new Date;
+
+        var attempt = function() {
+          var actual = _._VERSION;
+          if ((new Date - start) < limit && typeof actual != 'string') {
+            setTimeout(attempt, 16);
+            return;
+          }
+          assert.strictEqual(actual, _.VERSION);
+          done();
+        };
+
+        attempt();
+      }
+      else {
+        skipAssert(assert);
+        done();
+      }
+    });
+
+    QUnit.test('should not add `Function.prototype` extensions to lodash', function(assert) {
+      assert.expect(1);
+
+      if (lodashBizarro) {
+        assert.notOk('_method' in lodashBizarro);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should avoid non-native built-ins', function(assert) {
+      assert.expect(7);
+
+      function message(lodashMethod, nativeMethod) {
+        return '`' + lodashMethod + '` should avoid overwritten native `' + nativeMethod + '`';
+      }
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var object = { 'a': 1 },
+          otherObject = { 'b': 2 },
+          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
+
+      if (lodashBizarro) {
+        try {
+          var actual = lodashBizarro.keysIn(new Foo).sort();
+        } catch (e) {
+          actual = null;
+        }
+        var label = message('_.keysIn', 'Object#propertyIsEnumerable');
+        assert.deepEqual(actual, ['a', 'b'], label);
+
+        try {
+          var actual = lodashBizarro.isEmpty({});
+        } catch (e) {
+          actual = null;
+        }
+        var label = message('_.isEmpty', 'Object#propertyIsEnumerable');
+        assert.strictEqual(actual, true, label);
+
+        try {
+          actual = [
+            lodashBizarro.difference([object, otherObject], largeArray),
+            lodashBizarro.intersection(largeArray, [object]),
+            lodashBizarro.uniq(largeArray)
+          ];
+        } catch (e) {
+          actual = null;
+        }
+        label = message('_.difference`, `_.intersection`, and `_.uniq', 'Object.create` and `Map');
+        assert.deepEqual(actual, [[otherObject], [object], [object]], label);
+
+        try {
+          if (Symbol) {
+            object[symbol] = {};
+          }
+          actual = [
+            lodashBizarro.clone(object),
+            lodashBizarro.cloneDeep(object)
+          ];
+        } catch (e) {
+          actual = null;
+        }
+        label = message('_.clone` and `_.cloneDeep', 'Object.getOwnPropertySymbols');
+        assert.deepEqual(actual, [object, object], label);
+
+        try {
+          var symObject = Object(symbol);
+
+          // Avoid symbol detection in Babel's `typeof` helper.
+          symObject.constructor = Object;
+
+          actual = [
+            Symbol ? lodashBizarro.clone(symObject) : { 'constructor': Object },
+            Symbol ? lodashBizarro.isEqual(symObject, Object(symbol)) : false,
+            Symbol ? lodashBizarro.toString(symObject) : ''
+          ];
+        } catch (e) {
+          actual = null;
+        }
+        label = message('_.clone`, `_.isEqual`, and `_.toString', 'Symbol');
+        assert.deepEqual(actual, [{ 'constructor': Object }, false, ''], label);
+
+        try {
+          var map = new lodashBizarro.memoize.Cache;
+          actual = map.set('a', 1).get('a');
+        } catch (e) {
+          actual = null;
+        }
+        label = message('_.memoize.Cache', 'Map');
+        assert.deepEqual(actual, 1, label);
+
+        try {
+          map = new (Map || Object);
+          if (Symbol && Symbol.iterator) {
+            map[Symbol.iterator] = null;
+          }
+          actual = lodashBizarro.toArray(map);
+        } catch (e) {
+          actual = null;
+        }
+        label = message('_.toArray', 'Map');
+        assert.deepEqual(actual, [], label);
+      }
+      else {
+        skipAssert(assert, 7);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('isIndex');
+
+  (function() {
+    var func = _._isIndex;
+
+    QUnit.test('should return `true` for indexes', function(assert) {
+      assert.expect(1);
+
+      if (func) {
+        var values = [[0], ['0'], ['1'], [3, 4], [MAX_SAFE_INTEGER - 1]],
+            expected = lodashStable.map(values, alwaysTrue);
+
+        var actual = lodashStable.map(values, function(args) {
+          return func.apply(undefined, args);
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non-indexes', function(assert) {
+      assert.expect(1);
+
+      if (func) {
+        var values = [['1abc'], ['07'], ['0001'], [-1], [3, 3], [1.1], [MAX_SAFE_INTEGER]],
+            expected = lodashStable.map(values, alwaysFalse);
+
+        var actual = lodashStable.map(values, function(args) {
+          return func.apply(undefined, args);
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('isIterateeCall');
+
+  (function() {
+    var array = [1],
+        func = _._isIterateeCall,
+        object =  { 'a': 1 };
+
+    QUnit.test('should return `true` for iteratee calls', function(assert) {
+      assert.expect(3);
+
+      function Foo() {}
+      Foo.prototype.a = 1;
+
+      if (func) {
+        assert.strictEqual(func(1, 0, array), true);
+        assert.strictEqual(func(1, 'a', object), true);
+        assert.strictEqual(func(1, 'a', new Foo), true);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should return `false` for non-iteratee calls', function(assert) {
+      assert.expect(4);
+
+      if (func) {
+        assert.strictEqual(func(2, 0, array), false);
+        assert.strictEqual(func(1, 1.1, array), false);
+        assert.strictEqual(func(1, 0, { 'length': MAX_SAFE_INTEGER + 1 }), false);
+        assert.strictEqual(func(1, 'b', object), false);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should work with `NaN` values', function(assert) {
+      assert.expect(2);
+
+      if (func) {
+        assert.strictEqual(func(NaN, 0, [NaN]), true);
+        assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should not error when `index` is an object without a `toString` method', function(assert) {
+      assert.expect(1);
+
+      if (func) {
+        try {
+          var actual = func(1, { 'toString': null }, [1]);
+        } catch (e) {
+          var message = e.message;
+        }
+        assert.strictEqual(actual, false, message || '');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash constructor');
+
+  (function() {
+    var values = empties.concat(true, 1, 'a'),
+        expected = lodashStable.map(values, alwaysTrue);
+
+    QUnit.test('should create a new instance when called without the `new` operator', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = lodashStable.map(values, function(value) {
+          return _(value) instanceof _;
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return the given `lodash` instances', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = lodashStable.map(values, function(value) {
+          var wrapped = _(value);
+          return _(wrapped) === wrapped;
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should convert foreign wrapped values to `lodash` instances', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm && lodashBizarro) {
+        var actual = lodashStable.map(values, function(value) {
+          var wrapped = _(lodashBizarro(value)),
+              unwrapped = wrapped.value();
+
+          return wrapped instanceof _ &&
+            ((unwrapped === value) || (unwrapped !== unwrapped && value !== value));
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.add');
+
+  (function() {
+    QUnit.test('should add two numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.add(6, 4), 10);
+      assert.strictEqual(_.add(-6, 4), -2);
+      assert.strictEqual(_.add(-6, -4), -10);
+    });
+
+    QUnit.test('should not coerce arguments to numbers', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.add('6', '4'), '64');
+      assert.strictEqual(_.add('x', 'y'), 'xy');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.after');
+
+  (function() {
+    function after(n, times) {
+      var count = 0;
+      lodashStable.times(times, _.after(n, function() { count++; }));
+      return count;
+    }
+
+    QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(after(5, 5), 1, 'after(n) should invoke `func` after being called `n` times');
+      assert.strictEqual(after(5, 4), 0, 'after(n) should not invoke `func` before being called `n` times');
+      assert.strictEqual(after(0, 0), 0, 'after(0) should not invoke `func` immediately');
+      assert.strictEqual(after(0, 1), 1, 'after(0) should invoke `func` when called once');
+    });
+
+    QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(after(NaN, 1), 1);
+    });
+
+    QUnit.test('should not set a `this` binding', function(assert) {
+      assert.expect(2);
+
+      var after = _.after(1, function(assert) { return ++this.count; }),
+          object = { 'after': after, 'count': 0 };
+
+      object.after();
+      assert.strictEqual(object.after(), 2);
+      assert.strictEqual(object.count, 2);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.ary');
+
+  (function() {
+    function fn(a, b, c) {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
+      assert.expect(2);
+
+      var actual = lodashStable.map(['6', '8', '10'], _.ary(parseInt, 1));
+      assert.deepEqual(actual, [6, 8, 10]);
+
+      var capped = _.ary(fn, 2);
+      assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b']);
+    });
+
+    QUnit.test('should use `func.length` if `n` is not given', function(assert) {
+      assert.expect(1);
+
+      var capped = _.ary(fn);
+      assert.deepEqual(capped('a', 'b', 'c', 'd'), ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should treat a negative `n` as `0`', function(assert) {
+      assert.expect(1);
+
+      var capped = _.ary(fn, -1);
+
+      try {
+        var actual = capped('a');
+      } catch (e) {}
+
+      assert.deepEqual(actual, []);
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(1);
+
+      var values = ['1', 1.6, 'xyz'],
+          expected = [['a'], ['a'], []];
+
+      var actual = lodashStable.map(values, function(n) {
+        var capped = _.ary(fn, n);
+        return capped('a', 'b');
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work when given less than the capped number of arguments', function(assert) {
+      assert.expect(1);
+
+      var capped = _.ary(fn, 3);
+      assert.deepEqual(capped('a'), ['a']);
+    });
+
+    QUnit.test('should use the existing `ary` if smaller', function(assert) {
+      assert.expect(1);
+
+      var capped = _.ary(_.ary(fn, 1), 2);
+      assert.deepEqual(capped('a', 'b', 'c'), ['a']);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var funcs = lodashStable.map([fn], _.ary),
+          actual = funcs[0]('a', 'b', 'c');
+
+      assert.deepEqual(actual, ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should work when combined with other methods that use metadata', function(assert) {
+      assert.expect(2);
+
+      var array = ['a', 'b', 'c'],
+          includes = _.curry(_.rearg(_.ary(_.includes, 2), 1, 0), 2);
+
+      assert.strictEqual(includes('b')(array, 2), true);
+
+      if (!isNpm) {
+        includes = _(_.includes).ary(2).rearg(1, 0).curry(2).value();
+        assert.strictEqual(includes('b')(array, 2), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.assignIn');
+
+  (function() {
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.extend, _.assignIn);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.assign and lodash.assignIn');
+
+  lodashStable.each(['assign', 'assignIn'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should assign source properties to `object`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }), { 'a': 1, 'b': 2 });
+    });
+
+    QUnit.test('`_.' + methodName + '` should accept multiple sources', function(assert) {
+      assert.expect(2);
+
+      var expected = { 'a': 1, 'b': 2, 'c': 3 };
+      assert.deepEqual(func({ 'a': 1 }, { 'b': 2 }, { 'c': 3 }), expected);
+      assert.deepEqual(func({ 'a': 1 }, { 'b': 2, 'c': 2 }, { 'c': 3 }), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should overwrite destination properties', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'a': 3, 'b': 2, 'c': 1 };
+      assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should assign source properties with nullish values', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'a': null, 'b': undefined, 'c': null };
+      assert.deepEqual(func({ 'a': 1, 'b': 2 }, expected), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should skip assignments if values are the same', function(assert) {
+      assert.expect(1);
+
+      var object = {};
+
+      var descriptor = {
+        'configurable': true,
+        'enumerable': true,
+        'set': function() { throw new Error; }
+      };
+
+      var source = {
+        'a': 1,
+        'b': undefined,
+        'c': NaN,
+        'd': undefined,
+        'constructor': Object,
+        'toString': lodashStable.constant('source')
+      };
+
+      defineProperty(object, 'a', lodashStable.assign({}, descriptor, {
+        'get': alwaysOne
+      }));
+
+      defineProperty(object, 'b', lodashStable.assign({}, descriptor, {
+        'get': noop
+      }));
+
+      defineProperty(object, 'c', lodashStable.assign({}, descriptor, {
+        'get': alwaysNaN
+      }));
+
+      defineProperty(object, 'constructor', lodashStable.assign({}, descriptor, {
+        'get': lodashStable.constant(Object)
+      }));
+
+      try {
+        var actual = func(object, source);
+      } catch (e) {}
+
+      assert.deepEqual(actual, source);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat sparse array sources as dense', function(assert) {
+      assert.expect(1);
+
+      var array = [1];
+      array[2] = 3;
+
+      assert.deepEqual(func({}, array), { '0': 1, '1': undefined, '2': 3 });
+    });
+
+    QUnit.test('`_.' + methodName + '` should assign values of prototype objects', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype.a = 1;
+
+      assert.deepEqual(func({}, Foo.prototype), { 'a': 1 });
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce string sources to objects', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func({}, 'a'), { '0': 'a' });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.assignInWith');
+
+  (function() {
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.extendWith, _.assignInWith);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.assignWith and lodash.assignInWith');
+
+  lodashStable.each(['assignWith', 'assignInWith'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should work with a `customizer` callback', function(assert) {
+      assert.expect(1);
+
+      var actual = func({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) {
+        return a === undefined ? b : a;
+      });
+
+      assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a `customizer` that returns `undefined`', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'a': undefined };
+      assert.deepEqual(func({}, expected, noop), expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.at');
+
+  (function() {
+    var args = arguments,
+        array = ['a', 'b', 'c'],
+        object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
+
+    QUnit.test('should return the elements corresponding to the specified keys', function(assert) {
+      assert.expect(1);
+
+      var actual = _.at(array, [0, 2]);
+      assert.deepEqual(actual, ['a', 'c']);
+    });
+
+    QUnit.test('should return `undefined` for nonexistent keys', function(assert) {
+      assert.expect(1);
+
+      var actual = _.at(array, [2, 4, 0]);
+      assert.deepEqual(actual, ['c', undefined, 'a']);
+    });
+
+    QUnit.test('should work with non-index keys on array values', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.reject(empties, function(value) {
+        return (value === 0) || lodashStable.isArray(value);
+      }).concat(-1, 1.1);
+
+      var array = lodashStable.transform(values, function(result, value) {
+        result[value] = 1;
+      }, []);
+
+      var expected = lodashStable.map(values, alwaysOne),
+          actual = _.at(array, values);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an empty array when no keys are given', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.at(array), []);
+      assert.deepEqual(_.at(array, [], []), []);
+    });
+
+    QUnit.test('should accept multiple key arguments', function(assert) {
+      assert.expect(1);
+
+      var actual = _.at(['a', 'b', 'c', 'd'], 3, 0, 2);
+      assert.deepEqual(actual, ['d', 'a', 'c']);
+    });
+
+    QUnit.test('should work with a falsey `object` argument when keys are given', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, lodashStable.constant(Array(4)));
+
+      var actual = lodashStable.map(falsey, function(object) {
+        try {
+          return _.at(object, 0, 1, 'pop', 'push');
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with an `arguments` object for `object`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.at(args, [2, 0]);
+      assert.deepEqual(actual, [3, 1]);
+    });
+
+    QUnit.test('should work with `arguments` object as secondary arguments', function(assert) {
+      assert.expect(1);
+
+      var actual = _.at([1, 2, 3, 4, 5], args);
+      assert.deepEqual(actual, [2, 3, 4]);
+    });
+
+    QUnit.test('should work with an object for `object`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.at(object, ['a[0].b.c', 'a[1]']);
+      assert.deepEqual(actual, [3, 4]);
+    });
+
+    QUnit.test('should pluck inherited property values', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var actual = _.at(new Foo, 'b');
+      assert.deepEqual(actual, [2]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
+            smallArray = array;
+
+        lodashStable.each([[2], ['2'], [2, 1]], function(paths) {
+          lodashStable.times(2, function(index) {
+            var array = index ? largeArray : smallArray,
+                wrapped = _(array).map(identity).at(paths);
+
+            assert.deepEqual(wrapped.value(), _.at(_.map(array, identity), paths));
+          });
+        });
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+
+    QUnit.test('should support shortcut fusion', function(assert) {
+      assert.expect(8);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            count = 0,
+            iteratee = function(value) { count++; return square(value); },
+            lastIndex = LARGE_ARRAY_SIZE - 1;
+
+        lodashStable.each([lastIndex, lastIndex + '', LARGE_ARRAY_SIZE, []], function(n, index) {
+          count = 0;
+          var actual = _(array).map(iteratee).at(n).value(),
+              expected = index < 2 ? 1 : 0;
+
+          assert.strictEqual(count, expected);
+
+          expected = index == 3 ? [] : [index == 2 ? undefined : square(lastIndex)];
+          assert.deepEqual(actual, expected);
+        });
+      }
+      else {
+        skipAssert(assert, 8);
+      }
+    });
+
+    QUnit.test('work with an object for `object` when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var paths = ['a[0].b.c', 'a[1]'],
+            actual = _(object).map(identity).at(paths).value();
+
+        assert.deepEqual(actual, _.at(_.map(object, identity), paths));
+
+        var indexObject = { '0': 1 };
+        actual = _(indexObject).at(0).value();
+        assert.deepEqual(actual, _.at(indexObject, 0));
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.attempt');
+
+  (function() {
+    QUnit.test('should return the result of `func`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.attempt(lodashStable.constant('x')), 'x');
+    });
+
+    QUnit.test('should provide additional arguments to `func`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.attempt(function() { return slice.call(arguments); }, 1, 2);
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('should return the caught error', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(errors, alwaysTrue);
+
+      var actual = lodashStable.map(errors, function(error) {
+        return _.attempt(function() { throw error; }) === error;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce errors to error objects', function(assert) {
+      assert.expect(1);
+
+      var actual = _.attempt(function() { throw 'x'; });
+      assert.ok(lodashStable.isEqual(actual, Error('x')));
+    });
+
+    QUnit.test('should preserve custom errors', function(assert) {
+      assert.expect(1);
+
+      var actual = _.attempt(function() { throw new CustomError('x'); });
+      assert.ok(actual instanceof CustomError);
+    });
+
+    QUnit.test('should work with an error object from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.errors) {
+        var expected = lodashStable.map(realm.errors, alwaysTrue);
+
+        var actual = lodashStable.map(realm.errors, function(error) {
+          return _.attempt(function() { throw error; }) === error;
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.before');
+
+  (function() {
+    function before(n, times) {
+      var count = 0;
+      lodashStable.times(times, _.before(n, function() { count++; }));
+      return count;
+    }
+
+    QUnit.test('should create a function that invokes `func` after `n` calls', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(before(5, 4), 4, 'before(n) should invoke `func` before being called `n` times');
+      assert.strictEqual(before(5, 6), 4, 'before(n) should not invoke `func` after being called `n - 1` times');
+      assert.strictEqual(before(0, 0), 0, 'before(0) should not invoke `func` immediately');
+      assert.strictEqual(before(0, 1), 0, 'before(0) should not invoke `func` when called');
+    });
+
+    QUnit.test('should coerce `n` values of `NaN` to `0`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(before(NaN, 1), 0);
+    });
+
+    QUnit.test('should not set a `this` binding', function(assert) {
+      assert.expect(2);
+
+      var before = _.before(2, function(assert) { return ++this.count; }),
+          object = { 'before': before, 'count': 0 };
+
+      object.before();
+      assert.strictEqual(object.before(), 1);
+      assert.strictEqual(object.count, 1);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.bind');
+
+  (function() {
+    function fn() {
+      var result = [this];
+      push.apply(result, arguments);
+      return result;
+    }
+
+    QUnit.test('should bind a function to an object', function(assert) {
+      assert.expect(1);
+
+      var object = {},
+          bound = _.bind(fn, object);
+
+      assert.deepEqual(bound('a'), [object, 'a']);
+    });
+
+    QUnit.test('should accept a falsey `thisArg` argument', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.reject(falsey.slice(1), function(value) { return value == null; }),
+          expected = lodashStable.map(values, function(value) { return [value]; });
+
+      var actual = lodashStable.map(values, function(value) {
+        try {
+          var bound = _.bind(fn, value);
+          return bound();
+        } catch (e) {}
+      });
+
+      assert.ok(lodashStable.every(actual, function(value, index) {
+        return lodashStable.isEqual(value, expected[index]);
+      }));
+    });
+
+    QUnit.test('should bind a function to nullish values', function(assert) {
+      assert.expect(6);
+
+      var bound = _.bind(fn, null),
+          actual = bound('a');
+
+      assert.ok((actual[0] === null) || (actual[0] && actual[0].Array));
+      assert.strictEqual(actual[1], 'a');
+
+      lodashStable.times(2, function(index) {
+        bound = index ? _.bind(fn, undefined) : _.bind(fn);
+        actual = bound('b');
+
+        assert.ok((actual[0] === undefined) || (actual[0] && actual[0].Array));
+        assert.strictEqual(actual[1], 'b');
+      });
+    });
+
+    QUnit.test('should partially apply arguments ', function(assert) {
+      assert.expect(4);
+
+      var object = {},
+          bound = _.bind(fn, object, 'a');
+
+      assert.deepEqual(bound(), [object, 'a']);
+
+      bound = _.bind(fn, object, 'a');
+      assert.deepEqual(bound('b'), [object, 'a', 'b']);
+
+      bound = _.bind(fn, object, 'a', 'b');
+      assert.deepEqual(bound(), [object, 'a', 'b']);
+      assert.deepEqual(bound('c', 'd'), [object, 'a', 'b', 'c', 'd']);
+    });
+
+    QUnit.test('should support placeholders', function(assert) {
+      assert.expect(4);
+
+      var object = {},
+          ph = _.bind.placeholder,
+          bound = _.bind(fn, object, ph, 'b', ph);
+
+      assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', 'c']);
+      assert.deepEqual(bound('a'), [object, 'a', 'b', undefined]);
+      assert.deepEqual(bound('a', 'c', 'd'), [object, 'a', 'b', 'c', 'd']);
+      assert.deepEqual(bound(), [object, undefined, 'b', undefined]);
+    });
+
+    QUnit.test('should use `_.placeholder` when set', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var _ph = _.placeholder = {},
+            ph = _.bind.placeholder,
+            object = {},
+            bound = _.bind(fn, object, _ph, 'b', ph);
+
+        assert.deepEqual(bound('a', 'c'), [object, 'a', 'b', ph, 'c']);
+        delete _.placeholder;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should create a function with a `length` of `0`', function(assert) {
+      assert.expect(2);
+
+      var fn = function(a, b, c) {},
+          bound = _.bind(fn, {});
+
+      assert.strictEqual(bound.length, 0);
+
+      bound = _.bind(fn, {}, 1);
+      assert.strictEqual(bound.length, 0);
+    });
+
+    QUnit.test('should ignore binding when called with the `new` operator', function(assert) {
+      assert.expect(3);
+
+      function Foo() {
+        return this;
+      }
+
+      var bound = _.bind(Foo, { 'a': 1 }),
+          newBound = new bound;
+
+      assert.strictEqual(bound().a, 1);
+      assert.strictEqual(newBound.a, undefined);
+      assert.ok(newBound instanceof Foo);
+    });
+
+    QUnit.test('should handle a number of arguments when called with the `new` operator', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        return this;
+      }
+
+      function Bar() {}
+
+      var thisArg = { 'a': 1 },
+          boundFoo = _.bind(Foo, thisArg),
+          boundBar = _.bind(Bar, thisArg),
+          count = 9,
+          expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
+
+      var actual = lodashStable.times(count, function(index) {
+        try {
+          switch (index) {
+            case 0: return [new boundFoo().a, new boundBar().a];
+            case 1: return [new boundFoo(1).a, new boundBar(1).a];
+            case 2: return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
+            case 3: return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
+            case 4: return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
+            case 5: return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
+            case 6: return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
+            case 7: return [new boundFoo(1, 2, 3, 4, 5, 6, 7).a, new boundBar(1, 2, 3, 4, 5, 6, 7).a];
+            case 8: return [new boundFoo(1, 2, 3, 4, 5, 6, 7, 8).a, new boundBar(1, 2, 3, 4, 5, 6, 7, 8).a];
+          }
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should ensure `new bound` is an instance of `func`', function(assert) {
+      assert.expect(2);
+
+      function Foo(value) {
+        return value && object;
+      }
+
+      var bound = _.bind(Foo),
+          object = {};
+
+      assert.ok(new bound instanceof Foo);
+      assert.strictEqual(new bound(true), object);
+    });
+
+    QUnit.test('should append array arguments to partially applied arguments', function(assert) {
+      assert.expect(1);
+
+      var object = {},
+          bound = _.bind(fn, object, 'a');
+
+      assert.deepEqual(bound(['b'], 'c'), [object, 'a', ['b'], 'c']);
+    });
+
+    QUnit.test('should not rebind functions', function(assert) {
+      assert.expect(3);
+
+      var object1 = {},
+          object2 = {},
+          object3 = {};
+
+      var bound1 = _.bind(fn, object1),
+          bound2 = _.bind(bound1, object2, 'a'),
+          bound3 = _.bind(bound1, object3, 'b');
+
+      assert.deepEqual(bound1(), [object1]);
+      assert.deepEqual(bound2(), [object1, 'a']);
+      assert.deepEqual(bound3(), [object1, 'b']);
+    });
+
+    QUnit.test('should not error when instantiating bound built-ins', function(assert) {
+      assert.expect(2);
+
+      var Ctor = _.bind(Date, null),
+          expected = new Date(2012, 4, 23, 0, 0, 0, 0);
+
+      try {
+        var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
+      } catch (e) {}
+
+      assert.deepEqual(actual, expected);
+
+      Ctor = _.bind(Date, null, 2012, 4, 23);
+
+      try {
+        actual = new Ctor(0, 0, 0, 0);
+      } catch (e) {}
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not error when calling bound class constructors with the `new` operator', function(assert) {
+      assert.expect(1);
+
+      var createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
+
+      if (typeof createCtor == 'function') {
+        var bound = _.bind(createCtor()),
+            count = 8,
+            expected = lodashStable.times(count, alwaysTrue);
+
+        var actual = lodashStable.times(count, function(index) {
+          try {
+            switch (index) {
+              case 0: return !!(new bound);
+              case 1: return !!(new bound(1));
+              case 2: return !!(new bound(1, 2));
+              case 3: return !!(new bound(1, 2, 3));
+              case 4: return !!(new bound(1, 2, 3, 4));
+              case 5: return !!(new bound(1, 2, 3, 4, 5));
+              case 6: return !!(new bound(1, 2, 3, 4, 5, 6));
+              case 7: return !!(new bound(1, 2, 3, 4, 5, 6, 7));
+            }
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var object = {},
+            bound = _(fn).bind({}, 'a', 'b');
+
+        assert.ok(bound instanceof _);
+
+        var actual = bound.value()('c');
+        assert.deepEqual(actual, [object, 'a', 'b', 'c']);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.bindAll');
+
+  (function() {
+    var args = arguments;
+
+    var source = {
+      '_n0': -2,
+      '_p0': -1,
+      '_a': 1,
+      '_b': 2,
+      '_c': 3,
+      '_d': 4,
+      '-0': function() { return this._n0; },
+      '0': function() { return this._p0; },
+      'a': function() { return this._a; },
+      'b': function() { return this._b; },
+      'c': function() { return this._c; },
+      'd': function() { return this._d; }
+    };
+
+    QUnit.test('should accept individual method names', function(assert) {
+      assert.expect(1);
+
+      var object = lodashStable.cloneDeep(source);
+      _.bindAll(object, 'a', 'b');
+
+      var actual = lodashStable.map(['a', 'b', 'c'], function(key) {
+        return object[key].call({});
+      });
+
+      assert.deepEqual(actual, [1, 2, undefined]);
+    });
+
+    QUnit.test('should accept arrays of method names', function(assert) {
+      assert.expect(1);
+
+      var object = lodashStable.cloneDeep(source);
+      _.bindAll(object, ['a', 'b'], ['c']);
+
+      var actual = lodashStable.map(['a', 'b', 'c', 'd'], function(key) {
+        return object[key].call({});
+      });
+
+      assert.deepEqual(actual, [1, 2, 3, undefined]);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var props = [-0, Object(-0), 0, Object(0)];
+
+      var actual = lodashStable.map(props, function(key) {
+        var object = lodashStable.cloneDeep(source);
+        _.bindAll(object, key);
+        return object[lodashStable.toString(key)].call({});
+      });
+
+      assert.deepEqual(actual, [-2, -2, -1, -1]);
+    });
+
+    QUnit.test('should work with an array `object` argument', function(assert) {
+      assert.expect(1);
+
+      var array = ['push', 'pop'];
+      _.bindAll(array);
+      assert.strictEqual(array.pop, arrayProto.pop);
+    });
+
+    QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
+      assert.expect(1);
+
+      var object = lodashStable.cloneDeep(source);
+      _.bindAll(object, args);
+
+      var actual = lodashStable.map(args, function(key) {
+        return object[key].call({});
+      });
+
+      assert.deepEqual(actual, [1]);
+    });
+  }('a'));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.bindKey');
+
+  (function() {
+    QUnit.test('should work when the target function is overwritten', function(assert) {
+      assert.expect(2);
+
+      var object = {
+        'user': 'fred',
+        'greet': function(greeting) {
+          return this.user + ' says: ' + greeting;
+        }
+      };
+
+      var bound = _.bindKey(object, 'greet', 'hi');
+      assert.strictEqual(bound(), 'fred says: hi');
+
+      object.greet = function(greeting) {
+        return this.user + ' says: ' + greeting + '!';
+      };
+
+      assert.strictEqual(bound(), 'fred says: hi!');
+    });
+
+    QUnit.test('should support placeholders', function(assert) {
+      assert.expect(4);
+
+      var object = {
+        'fn': function() {
+          return slice.call(arguments);
+        }
+      };
+
+      var ph = _.bindKey.placeholder,
+          bound = _.bindKey(object, 'fn', ph, 'b', ph);
+
+      assert.deepEqual(bound('a', 'c'), ['a', 'b', 'c']);
+      assert.deepEqual(bound('a'), ['a', 'b', undefined]);
+      assert.deepEqual(bound('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
+      assert.deepEqual(bound(), [undefined, 'b', undefined]);
+    });
+
+    QUnit.test('should use `_.placeholder` when set', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var object = {
+          'fn': function() {
+            return slice.call(arguments);
+          }
+        };
+
+        var _ph = _.placeholder = {},
+            ph = _.bindKey.placeholder,
+            bound = _.bindKey(object, 'fn', _ph, 'b', ph);
+
+        assert.deepEqual(bound('a', 'c'), ['a', 'b', ph, 'c']);
+        delete _.placeholder;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should ensure `new bound` is an instance of `object[key]`', function(assert) {
+      assert.expect(2);
+
+      function Foo(value) {
+        return value && object;
+      }
+
+      var object = { 'Foo': Foo },
+          bound = _.bindKey(object, 'Foo');
+
+      assert.ok(new bound instanceof Foo);
+      assert.strictEqual(new bound(true), object);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('case methods');
+
+  lodashStable.each(['camel', 'kebab', 'lower', 'snake', 'start', 'upper'], function(caseName) {
+    var methodName = caseName + 'Case',
+        func = _[methodName];
+
+    var strings = [
+      'foo bar', 'Foo bar', 'foo Bar', 'Foo Bar',
+      'FOO BAR', 'fooBar', '--foo-bar--', '__foo_bar__'
+    ];
+
+    var converted = (function() {
+      switch (caseName) {
+        case 'camel': return 'fooBar';
+        case 'kebab': return 'foo-bar';
+        case 'lower': return 'foo bar';
+        case 'snake': return 'foo_bar';
+        case 'start': return 'Foo Bar';
+        case 'upper': return 'FOO BAR';
+      }
+    }());
+
+    QUnit.test('`_.' + methodName + '` should convert `string` to ' + caseName + ' case', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(strings, function(string) {
+        var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
+        return func(string) === expected;
+      });
+
+      assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
+    });
+
+    QUnit.test('`_.' + methodName + '` should handle double-converting strings', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(strings, function(string) {
+        var expected = (caseName == 'start' && string == 'FOO BAR') ? string : converted;
+        return func(func(string)) === expected;
+      });
+
+      assert.deepEqual(actual, lodashStable.map(strings, alwaysTrue));
+    });
+
+    QUnit.test('`_.' + methodName + '` should deburr letters', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(burredLetters, function(burred, index) {
+        var letter = deburredLetters[index];
+        if (caseName == 'start') {
+          letter = lodashStable.capitalize(letter);
+        } else if (caseName == 'upper') {
+          letter = letter.toUpperCase();
+        } else {
+          letter = letter.toLowerCase();
+        }
+        return func(burred) === letter;
+      });
+
+      assert.deepEqual(actual, lodashStable.map(burredLetters, alwaysTrue));
+    });
+
+    QUnit.test('`_.' + methodName + '` should remove contraction apostrophes', function(assert) {
+      assert.expect(2);
+
+      var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
+
+      lodashStable.each(["'", '\u2019'], function(apos) {
+        var actual = lodashStable.map(postfixes, function(postfix) {
+          return func('a b' + apos + postfix +  ' c');
+        });
+
+        var expected = lodashStable.map(postfixes, function(postfix) {
+          switch (caseName) {
+            case 'camel': return 'aB'  + postfix + 'C';
+            case 'kebab': return 'a-b' + postfix + '-c';
+            case 'lower': return 'a b' + postfix + ' c';
+            case 'snake': return 'a_b' + postfix + '_c';
+            case 'start': return 'A B' + postfix + ' C';
+            case 'upper': return 'A B' + postfix.toUpperCase() + ' C';
+          }
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should remove latin-1 mathematical operators', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(['\xd7', '\xf7'], func);
+      assert.deepEqual(actual, ['', '']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
+      assert.expect(2);
+
+      var string = 'foo bar';
+      assert.strictEqual(func(Object(string)), converted);
+      assert.strictEqual(func({ 'toString': lodashStable.constant(string) }), converted);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an unwrapped value implicitly when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_('foo bar')[methodName](), converted);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_('foo bar').chain()[methodName]() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  (function() {
+    QUnit.test('should get the original value after cycling through all case methods', function(assert) {
+      assert.expect(1);
+
+      var funcs = [_.camelCase, _.kebabCase, _.lowerCase, _.snakeCase, _.startCase, _.lowerCase, _.camelCase];
+
+      var actual = lodashStable.reduce(funcs, function(result, func) {
+        return func(result);
+      }, 'enable 6h format');
+
+      assert.strictEqual(actual, 'enable6HFormat');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.camelCase');
+
+  (function() {
+    QUnit.test('should work with numbers', function(assert) {
+      assert.expect(6);
+
+      assert.strictEqual(_.camelCase('12 feet'), '12Feet');
+      assert.strictEqual(_.camelCase('enable 6h format'), 'enable6HFormat');
+      assert.strictEqual(_.camelCase('enable 24H format'), 'enable24HFormat');
+      assert.strictEqual(_.camelCase('too legit 2 quit'), 'tooLegit2Quit');
+      assert.strictEqual(_.camelCase('walk 500 miles'), 'walk500Miles');
+      assert.strictEqual(_.camelCase('xhr2 request'), 'xhr2Request');
+    });
+
+    QUnit.test('should handle acronyms', function(assert) {
+      assert.expect(6);
+
+      lodashStable.each(['safe HTML', 'safeHTML'], function(string) {
+        assert.strictEqual(_.camelCase(string), 'safeHtml');
+      });
+
+      lodashStable.each(['escape HTML entities', 'escapeHTMLEntities'], function(string) {
+        assert.strictEqual(_.camelCase(string), 'escapeHtmlEntities');
+      });
+
+      lodashStable.each(['XMLHttpRequest', 'XmlHTTPRequest'], function(string) {
+        assert.strictEqual(_.camelCase(string), 'xmlHttpRequest');
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.capitalize');
+
+  (function() {
+    QUnit.test('should capitalize the first character of a string', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.capitalize('fred'), 'Fred');
+      assert.strictEqual(_.capitalize('Fred'), 'Fred');
+      assert.strictEqual(_.capitalize(' fred'), ' fred');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.castArray');
+
+  (function() {
+    QUnit.test('should wrap non-array items in an array', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat(true, 1, 'a', { 'a': 1 }),
+          expected = lodashStable.map(values, function(value) { return [value]; }),
+          actual = lodashStable.map(values, _.castArray);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return array values by reference', function(assert) {
+      assert.expect(1);
+
+      var array = [1];
+      assert.strictEqual(_.castArray(array), array);
+    });
+
+    QUnit.test('should return an empty array when no arguments are given', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.castArray(), []);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.chain');
+
+  (function() {
+    QUnit.test('should return a wrapped value', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = _.chain({ 'a': 0 });
+        assert.ok(actual instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return existing wrapped values', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _({ 'a': 0 });
+        assert.strictEqual(_.chain(wrapped), wrapped);
+        assert.strictEqual(wrapped.chain(), wrapped);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should enable chaining for methods that return unwrapped values', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var array = ['c', 'b', 'a'];
+
+        assert.ok(_.chain(array).head() instanceof _);
+        assert.ok(_(array).chain().head() instanceof _);
+
+        assert.ok(_.chain(array).isArray() instanceof _);
+        assert.ok(_(array).chain().isArray() instanceof _);
+
+        assert.ok(_.chain(array).sortBy().head() instanceof _);
+        assert.ok(_(array).chain().sortBy().head() instanceof _);
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+
+    QUnit.test('should chain multiple methods', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        lodashStable.times(2, function(index) {
+          var array = ['one two three four', 'five six seven eight', 'nine ten eleven twelve'],
+              expected = { ' ': 9, 'e': 14, 'f': 2, 'g': 1, 'h': 2, 'i': 4, 'l': 2, 'n': 6, 'o': 3, 'r': 2, 's': 2, 't': 5, 'u': 1, 'v': 4, 'w': 2, 'x': 1 },
+              wrapped = index ? _(array).chain() : _.chain(array);
+
+          var actual = wrapped
+            .chain()
+            .map(function(value) { return value.split(''); })
+            .flatten()
+            .reduce(function(object, chr) {
+              object[chr] || (object[chr] = 0);
+              object[chr]++;
+              return object;
+            }, {})
+            .value();
+
+          assert.deepEqual(actual, expected);
+
+          array = [1, 2, 3, 4, 5, 6];
+          wrapped = index ? _(array).chain() : _.chain(array);
+          actual = wrapped
+            .chain()
+            .filter(function(n) { return n % 2 != 0; })
+            .reject(function(n) { return n % 3 == 0; })
+            .sortBy(function(n) { return -n; })
+            .value();
+
+          assert.deepEqual(actual, [5, 1]);
+
+          array = [3, 4];
+          wrapped = index ? _(array).chain() : _.chain(array);
+          actual = wrapped
+            .reverse()
+            .concat([2, 1])
+            .unshift(5)
+            .tap(function(value) { value.pop(); })
+            .map(square)
+            .value();
+
+          assert.deepEqual(actual, [25, 16, 9, 4]);
+        });
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.chunk');
+
+  (function() {
+    var array = [0, 1, 2, 3, 4, 5];
+
+    QUnit.test('should return chunked arrays', function(assert) {
+      assert.expect(1);
+
+      var actual = _.chunk(array, 3);
+      assert.deepEqual(actual, [[0, 1, 2], [3, 4, 5]]);
+    });
+
+    QUnit.test('should return the last chunk as remaining elements', function(assert) {
+      assert.expect(1);
+
+      var actual = _.chunk(array, 4);
+      assert.deepEqual(actual, [[0, 1, 2, 3], [4, 5]]);
+    });
+
+    QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? [[0], [1], [2], [3], [4], [5]] : [];
+      });
+
+      var actual = lodashStable.map(falsey, function(size, index) {
+        return index ? _.chunk(array, size) : _.chunk(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should ensure the minimum `size` is `0`', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.reject(falsey, lodashStable.isUndefined).concat(-1, -Infinity),
+          expected = lodashStable.map(values, alwaysEmptyArray);
+
+      var actual = lodashStable.map(values, function(n) {
+        return _.chunk(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce `size` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.chunk(array, array.length / 4), [[0], [1], [2], [3], [4], [5]]);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map([[1, 2], [3, 4]], _.chunk);
+      assert.deepEqual(actual, [[[1], [2]], [[3], [4]]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.clamp');
+
+  (function() {
+    QUnit.test('should work with a `max` argument', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.clamp(5, 3), 3);
+      assert.strictEqual(_.clamp(1, 3), 1);
+    });
+
+    QUnit.test('should clamp negative numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.clamp(-10, -5, 5), -5);
+      assert.strictEqual(_.clamp(-10.2, -5.5, 5.5), -5.5);
+      assert.strictEqual(_.clamp(-Infinity, -5, 5), -5);
+    });
+
+    QUnit.test('should clamp positive numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.clamp(10, -5, 5), 5);
+      assert.strictEqual(_.clamp(10.6, -5.6, 5.4), 5.4);
+      assert.strictEqual(_.clamp(Infinity, -5, 5), 5);
+    });
+
+    QUnit.test('should not alter negative numbers in range', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.clamp(-4, -5, 5), -4);
+      assert.strictEqual(_.clamp(-5, -5, 5), -5);
+      assert.strictEqual(_.clamp(-5.5, -5.6, 5.6), -5.5);
+    });
+
+    QUnit.test('should not alter positive numbers in range', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.clamp(4, -5, 5), 4);
+      assert.strictEqual(_.clamp(5, -5, 5), 5);
+      assert.strictEqual(_.clamp(4.5, -5.1, 5.2), 4.5);
+    });
+
+    QUnit.test('should not alter `0` in range', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(1 / _.clamp(0, -5, 5), Infinity);
+    });
+
+    QUnit.test('should clamp to `0`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(1 / _.clamp(-10, 0, 5), Infinity);
+    });
+
+    QUnit.test('should not alter `-0` in range', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(1 / _.clamp(-0, -5, 5), -Infinity);
+    });
+
+    QUnit.test('should clamp to `-0`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(1 / _.clamp(-10, -0, 5), -Infinity);
+    });
+
+    QUnit.test('should return `NaN` when `number` is `NaN`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.clamp(NaN, -5, 5), NaN);
+    });
+
+    QUnit.test('should coerce `min` and `max` of `NaN` to `0`', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.clamp(1, -5, NaN), 0);
+      assert.deepEqual(_.clamp(-1, NaN, 5), 0);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('clone methods');
+
+  (function() {
+    function Foo() {
+      this.a = 1;
+    }
+    Foo.prototype.b = 1;
+    Foo.c = function() {};
+
+    if (Map) {
+      var map = new Map;
+      map.set('a', 1);
+      map.set('b', 2);
+    }
+    if (Set) {
+      var set = new Set;
+      set.add(1);
+      set.add(2);
+    }
+    var objects = {
+      '`arguments` objects': arguments,
+      'arrays': ['a', ''],
+      'array-like-objects': { '0': 'a', '1': '', 'length': 3 },
+      'booleans': false,
+      'boolean objects': Object(false),
+      'date objects': new Date,
+      'Foo instances': new Foo,
+      'objects': { 'a': 0, 'b': 1, 'c': 2 },
+      'objects with object values': { 'a': /a/, 'b': ['B'], 'c': { 'C': 1 } },
+      'objects from another document': realm.object || {},
+      'maps': map,
+      'null values': null,
+      'numbers': 0,
+      'number objects': Object(0),
+      'regexes': /a/gim,
+      'sets': set,
+      'strings': 'a',
+      'string objects': Object('a'),
+      'undefined values': undefined
+    };
+
+    objects.arrays.length = 3;
+
+    var uncloneable = {
+      'DOM elements': body,
+      'functions': Foo,
+      'generators': generator
+    };
+
+    lodashStable.each(errors, function(error) {
+      uncloneable[error.name + 's'] = error;
+    });
+
+    QUnit.test('`_.clone` should perform a shallow clone', function(assert) {
+      assert.expect(2);
+
+      var array = [{ 'a': 0 }, { 'b': 1 }],
+          actual = _.clone(array);
+
+      assert.deepEqual(actual, array);
+      assert.ok(actual !== array && actual[0] === array[0]);
+    });
+
+    QUnit.test('`_.cloneDeep` should deep clone objects with circular references', function(assert) {
+      assert.expect(1);
+
+      var object = {
+        'foo': { 'b': { 'c': { 'd': {} } } },
+        'bar': {}
+      };
+
+      object.foo.b.c.d = object;
+      object.bar.b = object.foo.b;
+
+      var actual = _.cloneDeep(object);
+      assert.ok(actual.bar.b === actual.foo.b && actual === actual.foo.b.c.d && actual !== object);
+    });
+
+    QUnit.test('`_.cloneDeep` should deep clone objects with lots of circular references', function(assert) {
+      assert.expect(2);
+
+      var cyclical = {};
+      lodashStable.times(LARGE_ARRAY_SIZE + 1, function(index) {
+        cyclical['v' + index] = [index ? cyclical['v' + (index - 1)] : cyclical];
+      });
+
+      var clone = _.cloneDeep(cyclical),
+          actual = clone['v' + LARGE_ARRAY_SIZE][0];
+
+      assert.strictEqual(actual, clone['v' + (LARGE_ARRAY_SIZE - 1)]);
+      assert.notStrictEqual(actual, cyclical['v' + (LARGE_ARRAY_SIZE - 1)]);
+    });
+
+    QUnit.test('`_.cloneDeepWith` should provide `stack` to `customizer`', function(assert) {
+      assert.expect(164);
+
+      var Stack,
+          keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || {}];
+
+      var pairs = lodashStable.map(keys, function(key, index) {
+        var lastIndex = keys.length - 1;
+        return [key, keys[lastIndex - index]];
+      });
+
+      _.cloneDeepWith({ 'a': 1 }, function() {
+        if (arguments.length > 1) {
+          Stack || (Stack = _.last(arguments).constructor);
+        }
+      });
+
+      var stacks = [new Stack(pairs), new Stack(pairs)];
+
+      lodashStable.times(LARGE_ARRAY_SIZE - pairs.length + 1, function() {
+        stacks[1].set({}, {});
+      });
+
+      lodashStable.each(stacks, function(stack) {
+        lodashStable.each(keys, function(key, index) {
+          var value = pairs[index][1];
+
+          assert.deepEqual(stack.get(key), value);
+          assert.strictEqual(stack.has(key), true);
+          assert.strictEqual(stack['delete'](key), true);
+          assert.strictEqual(stack.has(key), false);
+          assert.strictEqual(stack.get(key), undefined);
+          assert.strictEqual(stack['delete'](key), false);
+          assert.strictEqual(stack.set(key, value), stack);
+          assert.strictEqual(stack.has(key), true);
+        });
+
+        assert.strictEqual(stack.clear(), undefined);
+        assert.ok(lodashStable.every(keys, function(key) {
+          return !stack.has(key);
+        }));
+      });
+    });
+
+    lodashStable.each(['clone', 'cloneDeep'], function(methodName) {
+      var func = _[methodName],
+          isDeep = methodName == 'cloneDeep';
+
+      lodashStable.forOwn(objects, function(object, key) {
+        QUnit.test('`_.' + methodName + '` should clone ' + key, function(assert) {
+          assert.expect(2);
+
+          var isEqual = (key == 'maps' || key == 'sets') ? _.isEqual : lodashStable.isEqual,
+              actual = func(object);
+
+          assert.ok(isEqual(actual, object));
+
+          if (lodashStable.isObject(object)) {
+            assert.notStrictEqual(actual, object);
+          } else {
+            assert.strictEqual(actual, object);
+          }
+        });
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone array buffers', function(assert) {
+        assert.expect(2);
+
+        if (ArrayBuffer) {
+          var actual = func(arrayBuffer);
+          assert.strictEqual(actual.byteLength, arrayBuffer.byteLength);
+          assert.notStrictEqual(actual, arrayBuffer);
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone buffers', function(assert) {
+        assert.expect(4);
+
+        if (Buffer) {
+          var buffer = new Buffer([1, 2]),
+              actual = func(buffer);
+
+          assert.strictEqual(actual.byteLength, buffer.byteLength);
+          assert.strictEqual(actual.inspect(), buffer.inspect());
+          assert.notStrictEqual(actual, buffer);
+
+          buffer[0] = 2;
+          assert.strictEqual(actual[0], isDeep ? 2 : 1);
+        }
+        else {
+          skipAssert(assert, 4);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone `index` and `input` array properties', function(assert) {
+        assert.expect(2);
+
+        var array = /c/.exec('abcde'),
+            actual = func(array);
+
+        assert.strictEqual(actual.index, 2);
+        assert.strictEqual(actual.input, 'abcde');
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone `lastIndex` regexp property', function(assert) {
+        assert.expect(1);
+
+        var regexp = /c/g;
+        regexp.exec('abcde');
+
+        assert.strictEqual(func(regexp).lastIndex, 3);
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone expando properties', function(assert) {
+        assert.expect(1);
+
+        var values = lodashStable.map([false, true, 1, 'a'], function(value) {
+          var object = Object(value);
+          object.a = 1;
+          return object;
+        });
+
+        var expected = lodashStable.map(values, alwaysTrue);
+
+        var actual = lodashStable.map(values, function(value) {
+          return func(value).a === 1;
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone prototype objects', function(assert) {
+        assert.expect(2);
+
+        var actual = func(Foo.prototype);
+
+        assert.notOk(actual instanceof Foo);
+        assert.deepEqual(actual, { 'b': 1 });
+      });
+
+      QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone', function(assert) {
+        assert.expect(1);
+
+        assert.ok(func(new Foo) instanceof Foo);
+      });
+
+      QUnit.test('`_.' + methodName + '` should set the `[[Prototype]]` of a clone even when the `constructor` is incorrect', function(assert) {
+        assert.expect(1);
+
+        Foo.prototype.constructor = Object;
+        assert.ok(func(new Foo) instanceof Foo);
+        Foo.prototype.constructor = Foo;
+      });
+
+      QUnit.test('`_.' + methodName + '` should ensure `value` constructor is a function before using its `[[Prototype]]`', function(assert) {
+        assert.expect(1);
+
+        Foo.prototype.constructor = null;
+        assert.notOk(func(new Foo) instanceof Foo);
+        Foo.prototype.constructor = Foo;
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone properties that shadow those on `Object.prototype`', function(assert) {
+        assert.expect(2);
+
+        var object = {
+          'constructor': objectProto.constructor,
+          'hasOwnProperty': objectProto.hasOwnProperty,
+          'isPrototypeOf': objectProto.isPrototypeOf,
+          'propertyIsEnumerable': objectProto.propertyIsEnumerable,
+          'toLocaleString': objectProto.toLocaleString,
+          'toString': objectProto.toString,
+          'valueOf': objectProto.valueOf
+        };
+
+        var actual = func(object);
+
+        assert.deepEqual(actual, object);
+        assert.notStrictEqual(actual, object);
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone symbol properties', function(assert) {
+        assert.expect(3);
+
+        function Foo() {
+          this[symbol] = { 'c': 1 };
+        }
+
+        if (Symbol) {
+          var symbol2 = Symbol('b');
+          Foo.prototype[symbol2] = 2;
+
+          var object = { 'a': { 'b': new Foo } };
+          object[symbol] = { 'b': 1 };
+
+          var actual = func(object);
+
+          assert.deepEqual(getSymbols(actual.a.b), [symbol]);
+
+          if (isDeep) {
+            assert.deepEqual(actual[symbol], object[symbol]);
+            assert.deepEqual(actual.a.b[symbol], object.a.b[symbol]);
+          }
+          else {
+            assert.strictEqual(actual[symbol], object[symbol]);
+            assert.strictEqual(actual.a, object.a);
+          }
+        }
+        else {
+          skipAssert(assert, 3);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should clone symbol objects', function(assert) {
+        assert.expect(4);
+
+        if (Symbol) {
+          assert.strictEqual(func(symbol), symbol);
+
+          var object = Object(symbol),
+              actual = func(object);
+
+          assert.strictEqual(typeof actual, 'object');
+          assert.strictEqual(typeof actual.valueOf(), 'symbol');
+          assert.notStrictEqual(actual, object);
+        }
+        else {
+          skipAssert(assert, 4);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should not clone symbol primitives', function(assert) {
+        assert.expect(1);
+
+        if (Symbol) {
+          assert.strictEqual(func(symbol), symbol);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should not error on DOM elements', function(assert) {
+        assert.expect(1);
+
+        if (document) {
+          var element = document.createElement('div');
+
+          try {
+            assert.deepEqual(func(element), {});
+          } catch (e) {
+            assert.ok(false, e.message);
+          }
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should create an object from the same realm as `value`', function(assert) {
+        assert.expect(1);
+
+        var props = [];
+
+        var objects = lodashStable.transform(_, function(result, value, key) {
+          if (lodashStable.startsWith(key, '_') && lodashStable.isObject(value) &&
+              !lodashStable.isArguments(value) && !lodashStable.isElement(value) &&
+              !lodashStable.isFunction(value)) {
+            props.push(lodashStable.capitalize(lodashStable.camelCase(key)));
+            result.push(value);
+          }
+        }, []);
+
+        var expected = lodashStable.map(objects, alwaysTrue);
+
+        var actual = lodashStable.map(objects, function(object) {
+          var Ctor = object.constructor,
+              result = func(object);
+
+          return result !== object && ((result instanceof Ctor) || !(new Ctor instanceof Ctor));
+        });
+
+        assert.deepEqual(actual, expected, props.join(', '));
+      });
+
+      QUnit.test('`_.' + methodName + '` should perform a ' + (isDeep ? 'deep' : 'shallow') + ' clone when used as an iteratee for methods like `_.map`', function(assert) {
+        assert.expect(2);
+
+        var expected = [{ 'a': [0] }, { 'b': [1] }],
+            actual = lodashStable.map(expected, func);
+
+        assert.deepEqual(actual, expected);
+
+        if (isDeep) {
+          assert.ok(actual[0] !== expected[0] && actual[0].a !== expected[0].a && actual[1].b !== expected[1].b);
+        } else {
+          assert.ok(actual[0] !== expected[0] && actual[0].a === expected[0].a && actual[1].b === expected[1].b);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should return a unwrapped value when chaining', function(assert) {
+        assert.expect(2);
+
+        if (!isNpm) {
+          var object = objects.objects,
+              actual = _(object)[methodName]();
+
+          assert.deepEqual(actual, object);
+          assert.notStrictEqual(actual, object);
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+
+      lodashStable.each(arrayViews, function(type) {
+        QUnit.test('`_.' + methodName + '` should clone ' + type + ' values', function(assert) {
+          assert.expect(10);
+
+          var Ctor = root[type];
+
+          lodashStable.times(2, function(index) {
+            if (Ctor) {
+              var buffer = new ArrayBuffer(24),
+                  view = index ? new Ctor(buffer, 8, 1) : new Ctor(buffer),
+                  actual = func(view);
+
+              assert.deepEqual(actual, view);
+              assert.notStrictEqual(actual, view);
+              assert.strictEqual(actual.buffer === view.buffer, !isDeep);
+              assert.strictEqual(actual.byteOffset, view.byteOffset);
+              assert.strictEqual(actual.length, view.length);
+            }
+            else {
+              skipAssert(assert, 5);
+            }
+          });
+        });
+      });
+
+      lodashStable.forOwn(uncloneable, function(value, key) {
+        QUnit.test('`_.' + methodName + '` should not clone ' + key, function(assert) {
+          assert.expect(3);
+
+          if (value) {
+            var object = { 'a': value, 'b': { 'c': value } },
+                actual = func(object),
+                expected = (typeof value == 'function' && !!value.c) ? { 'c': Foo.c } : {};
+
+            assert.deepEqual(actual, object);
+            assert.notStrictEqual(actual, object);
+            assert.deepEqual(func(value), expected);
+          }
+          else {
+            skipAssert(assert, 3);
+          }
+        });
+      });
+    });
+
+    lodashStable.each(['cloneWith', 'cloneDeepWith'], function(methodName) {
+      var func = _[methodName],
+          isDeep = methodName == 'cloneDeepWith';
+
+      QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
+        assert.expect(1);
+
+        var argsList = [],
+            object = new Foo;
+
+        func(object, function() {
+          var length = arguments.length,
+              args = slice.call(arguments, 0, length - (length > 1 ? 1 : 0));
+
+          argsList.push(args);
+        });
+
+        assert.deepEqual(argsList, isDeep ? [[object], [1, 'a', object]] : [[object]]);
+      });
+
+      QUnit.test('`_.' + methodName + '` should handle cloning if `customizer` returns `undefined`', function(assert) {
+        assert.expect(1);
+
+        var actual = func({ 'a': { 'b': 'c' } }, noop);
+        assert.deepEqual(actual, { 'a': { 'b': 'c' } });
+      });
+
+      lodashStable.forOwn(uncloneable, function(value, key) {
+        QUnit.test('`_.' + methodName + '` should work with a `customizer` callback and ' + key, function(assert) {
+          assert.expect(4);
+
+          var customizer = function(value) {
+            return lodashStable.isPlainObject(value) ? undefined : value;
+          };
+
+          var actual = func(value, customizer);
+
+          assert.deepEqual(actual, value);
+          assert.strictEqual(actual, value);
+
+          var object = { 'a': value, 'b': { 'c': value } };
+          actual = func(object, customizer);
+
+          assert.deepEqual(actual, object);
+          assert.notStrictEqual(actual, object);
+        });
+      });
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.compact');
+
+  (function() {
+    var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null);
+
+    QUnit.test('should filter falsey values', function(assert) {
+      assert.expect(1);
+
+      var array = ['0', '1', '2'];
+      assert.deepEqual(_.compact(falsey.concat(array)), array);
+    });
+
+    QUnit.test('should work when in-between lazy operators', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var actual = _(falsey).thru(_.slice).compact().thru(_.slice).value();
+        assert.deepEqual(actual, []);
+
+        actual = _(falsey).thru(_.slice).push(true, 1).compact().push('a').value();
+        assert.deepEqual(actual, [true, 1, 'a']);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = _(largeArray).slice(1).compact().reverse().take().value();
+        assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse()));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var iteratee = _.iteratee,
+            pass = false;
+
+        _.iteratee = identity;
+
+        try {
+          var actual = _(largeArray).slice(1).compact().value();
+          pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1)));
+        } catch (e) {console.log(e);}
+
+        assert.ok(pass);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.concat');
+
+  (function() {
+    QUnit.test('should shallow clone `array`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          actual = _.concat(array);
+
+      assert.deepEqual(actual, array);
+      assert.notStrictEqual(actual, array);
+    });
+
+    QUnit.test('should concat arrays and values', function(assert) {
+      assert.expect(2);
+
+      var array = [1],
+          actual = _.concat(array, 2, [3], [[4]]);
+
+      assert.deepEqual(actual, [1, 2, 3, [4]]);
+      assert.deepEqual(array, [1]);
+    });
+
+    QUnit.test('should cast non-array `array` values to arrays', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined, false, true, 1, NaN, 'a'];
+
+      var expected = lodashStable.map(values, function(value, index) {
+        return index ? [value] : [];
+      });
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.concat(value) : _.concat();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(values, function(value) {
+        return [value, 2, [3]];
+      });
+
+      actual = lodashStable.map(values, function(value) {
+        return _.concat(value, [2], [[3]]);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat sparse arrays as dense', function(assert) {
+      assert.expect(3);
+
+      var expected = [],
+          actual = _.concat(Array(1), Array(1));
+
+      expected.push(undefined, undefined);
+
+      assert.ok('0'in actual);
+      assert.ok('1' in actual);
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return a new wrapped array', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array = [1],
+            wrapped = _(array).concat([2, 3]),
+            actual = wrapped.value();
+
+        assert.deepEqual(array, [1]);
+        assert.deepEqual(actual, [1, 2, 3]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.cond');
+
+  (function() {
+    QUnit.test('should create a conditional function', function(assert) {
+      assert.expect(3);
+
+      var cond = _.cond([
+        [lodashStable.matches({ 'a': 1 }),     alwaysA],
+        [lodashStable.matchesProperty('b', 1), alwaysB],
+        [lodashStable.property('c'),           alwaysC]
+      ]);
+
+      assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
+      assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
+      assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
+    });
+
+    QUnit.test('should provide arguments to functions', function(assert) {
+      assert.expect(2);
+
+      var args1,
+          args2,
+          expected = ['a', 'b', 'c'];
+
+      var cond = _.cond([[
+        function() { args1 || (args1 = slice.call(arguments)); return true; },
+        function() { args2 || (args2 = slice.call(arguments)); }
+      ]]);
+
+      cond('a', 'b', 'c');
+
+      assert.deepEqual(args1, expected);
+      assert.deepEqual(args2, expected);
+    });
+
+    QUnit.test('should work with predicate shorthands', function(assert) {
+      assert.expect(3);
+
+      var cond = _.cond([
+        [{ 'a': 1 }, alwaysA],
+        [['b', 1],   alwaysB],
+        ['c',        alwaysC]
+      ]);
+
+      assert.strictEqual(cond({ 'a':  1, 'b': 2, 'c': 3 }), 'a');
+      assert.strictEqual(cond({ 'a':  0, 'b': 1, 'c': 2 }), 'b');
+      assert.strictEqual(cond({ 'a': -1, 'b': 0, 'c': 1 }), 'c');
+    });
+
+    QUnit.test('should return `undefined` when no condition is met', function(assert) {
+      assert.expect(1);
+
+      var cond = _.cond([[alwaysFalse, alwaysA]]);
+      assert.strictEqual(cond({ 'a': 1 }), undefined);
+    });
+
+    QUnit.test('should throw a TypeError if `pairs` is not composed of functions', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([false, true], function(value) {
+        assert.raises(function() { _.cond([[alwaysTrue, value]])(); }, TypeError);
+      });
+    });
+
+    QUnit.test('should use `this` binding of function for `pairs`', function(assert) {
+      assert.expect(1);
+
+      var cond = _.cond([
+        [function(a) { return this[a]; }, function(a, b) { return this[b]; }]
+      ]);
+
+      var object = { 'cond': cond, 'a': 1, 'b': 2 };
+      assert.strictEqual(object.cond('a', 'b'), 2);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.conforms');
+
+  (function() {
+    var objects = [
+      { 'a': 1, 'b': 8 },
+      { 'a': 2, 'b': 4 },
+      { 'a': 3, 'b': 16 }
+    ];
+
+    QUnit.test('should create a function that checks if a given object conforms to `source`', function(assert) {
+      assert.expect(2);
+
+      var conforms = _.conforms({
+        'b': function(value) { return value > 4; }
+      });
+
+      var actual = lodashStable.filter(objects, conforms);
+      assert.deepEqual(actual, [objects[0], objects[2]]);
+
+      conforms = _.conforms({
+        'b': function(value) { return value > 8; },
+        'a': function(value) { return value > 1; }
+      });
+
+      actual = lodashStable.filter(objects, conforms);
+      assert.deepEqual(actual, [objects[2]]);
+    });
+
+    QUnit.test('should not match by inherited `source` properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = function(value) {
+          return value > 1;
+        };
+      }
+      Foo.prototype.b = function(value) {
+        return value > 8;
+      };
+
+      var conforms = _.conforms(new Foo),
+          actual = lodashStable.filter(objects, conforms);
+
+      assert.deepEqual(actual, [objects[1], objects[2]]);
+    });
+
+    QUnit.test('should not invoke `source` predicates for missing `object` properties', function(assert) {
+      assert.expect(2);
+
+      var count = 0;
+
+      var conforms = _.conforms({
+        'a': function() { count++; return true; }
+      });
+
+      assert.strictEqual(conforms({}), false);
+      assert.strictEqual(count, 0);
+    });
+
+    QUnit.test('should work with a function for `object`', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.a = 1;
+
+      function Bar() {}
+      Bar.a = 2;
+
+      var conforms = _.conforms({
+        'a': function(value) { return value > 1; }
+      });
+
+      assert.strictEqual(conforms(Foo), false);
+      assert.strictEqual(conforms(Bar), true);
+    });
+
+    QUnit.test('should work with a function for `source`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.a = function(value) { return value > 1; };
+
+      var objects = [{ 'a': 1 }, { 'a': 2 }],
+          actual = lodashStable.filter(objects, _.conforms(Foo));
+
+      assert.deepEqual(actual, [objects[1]]);
+    });
+
+    QUnit.test('should work with a non-plain `object`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var conforms = _.conforms({
+        'b': function(value) { return value > 1; }
+      });
+
+      assert.strictEqual(conforms(new Foo), true);
+    });
+
+    QUnit.test('should return `false` when `object` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var conforms = _.conforms({
+        'a': function(value) { return value > 1; }
+      });
+
+      var actual = lodashStable.map(values, function(value, index) {
+        try {
+          return index ? conforms(value) : conforms();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysTrue),
+          conforms = _.conforms({});
+
+      var actual = lodashStable.map(values, function(value, index) {
+        try {
+          return index ? conforms(value) : conforms();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1 },
+          expected = lodashStable.map(empties, alwaysTrue);
+
+      var actual = lodashStable.map(empties, function(value) {
+        var conforms = _.conforms(value);
+        return conforms(object);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not change behavior if `source` is modified', function(assert) {
+      assert.expect(2);
+
+      var source = {
+        'a': function(value) { return value > 1; }
+      };
+
+      var object = { 'a': 2 },
+          conforms = _.conforms(source);
+
+      assert.strictEqual(conforms(object), true);
+
+      source.a = function(value) { return value < 2; };
+      assert.strictEqual(conforms(object), true);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.constant');
+
+  (function() {
+    QUnit.test('should create a function that returns `value`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1 },
+          values = Array(2).concat(empties, true, 1, 'a'),
+          constant = _.constant(object),
+          expected = lodashStable.map(values, function() { return true; });
+
+      var actual = lodashStable.map(values, function(value, index) {
+        if (index == 0) {
+          var result = constant();
+        } else if (index == 1) {
+          result = constant.call({});
+        } else {
+          result = constant(value);
+        }
+        return result === object;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with falsey values', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function() { return true; });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        var constant = index ? _.constant(value) : _.constant(),
+            result = constant();
+
+        return (result === value) || (result !== result && value !== value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _(true).constant();
+        assert.ok(wrapped instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.countBy');
+
+  (function() {
+    var array = [6.1, 4.2, 6.3];
+
+    QUnit.test('should transform keys by `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.countBy(array, Math.floor);
+      assert.deepEqual(actual, { '4': 1, '6': 2 });
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var array = [4, 6, 6],
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant({ '4': 1, '6':  2 }));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.countBy(array, value) : _.countBy(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var actual = _.countBy(['one', 'two', 'three'], 'length');
+      assert.deepEqual(actual, { '3': 2, '5': 1 });
+    });
+
+    QUnit.test('should only add values to own, not inherited, properties', function(assert) {
+      assert.expect(2);
+
+      var actual = _.countBy(array, function(n) {
+        return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
+      });
+
+      assert.deepEqual(actual.constructor, 1);
+      assert.deepEqual(actual.hasOwnProperty, 2);
+    });
+
+    QUnit.test('should work with a number for `iteratee`', function(assert) {
+      assert.expect(2);
+
+      var array = [
+        [1, 'a'],
+        [2, 'a'],
+        [2, 'b']
+      ];
+
+      assert.deepEqual(_.countBy(array, 0), { '1': 1, '2': 2 });
+      assert.deepEqual(_.countBy(array, 1), { 'a': 2, 'b': 1 });
+    });
+
+    QUnit.test('should work with an object for `collection`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.countBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
+      assert.deepEqual(actual, { '4': 1, '6': 2 });
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
+          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
+          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
+        );
+
+        var actual = _(array).countBy().map(square).filter(isEven).take().value();
+
+        assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven)));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.create');
+
+  (function() {
+    function Shape() {
+      this.x = 0;
+      this.y = 0;
+    }
+
+    function Circle() {
+      Shape.call(this);
+    }
+
+    QUnit.test('should create an object that inherits from the given `prototype` object', function(assert) {
+      assert.expect(3);
+
+      Circle.prototype = _.create(Shape.prototype);
+      Circle.prototype.constructor = Circle;
+
+      var actual = new Circle;
+
+      assert.ok(actual instanceof Circle);
+      assert.ok(actual instanceof Shape);
+      assert.notStrictEqual(Circle.prototype, Shape.prototype);
+    });
+
+    QUnit.test('should assign `properties` to the created object', function(assert) {
+      assert.expect(3);
+
+      var expected = { 'constructor': Circle, 'radius': 0 };
+      Circle.prototype = _.create(Shape.prototype, expected);
+
+      var actual = new Circle;
+
+      assert.ok(actual instanceof Circle);
+      assert.ok(actual instanceof Shape);
+      assert.deepEqual(Circle.prototype, expected);
+    });
+
+    QUnit.test('should assign own properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+        this.c = 3;
+      }
+      Foo.prototype.b = 2;
+
+      assert.deepEqual(_.create({}, new Foo), { 'a': 1, 'c': 3 });
+    });
+
+    QUnit.test('should assign properties that shadow those of `prototype`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      var object = _.create(new Foo, { 'a': 1 });
+      assert.deepEqual(lodashStable.keys(object), ['a']);
+    });
+
+    QUnit.test('should accept a falsey `prototype` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyObject);
+
+      var actual = lodashStable.map(falsey, function(prototype, index) {
+        return index ? _.create(prototype) : _.create();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should ignore primitive `prototype` arguments and use an empty object instead', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(primitives, alwaysTrue);
+
+      var actual = lodashStable.map(primitives, function(value, index) {
+        return lodashStable.isPlainObject(index ? _.create(value) : _.create());
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [{ 'a': 1 }, { 'a': 1 }, { 'a': 1 }],
+          expected = lodashStable.map(array, alwaysTrue),
+          objects = lodashStable.map(array, _.create);
+
+      var actual = lodashStable.map(objects, function(object) {
+        return object.a === 1 && !_.keys(object).length;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.curry');
+
+  (function() {
+    function fn(a, b, c, d) {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should curry based on the number of arguments given', function(assert) {
+      assert.expect(3);
+
+      var curried = _.curry(fn),
+          expected = [1, 2, 3, 4];
+
+      assert.deepEqual(curried(1)(2)(3)(4), expected);
+      assert.deepEqual(curried(1, 2)(3, 4), expected);
+      assert.deepEqual(curried(1, 2, 3, 4), expected);
+    });
+
+    QUnit.test('should allow specifying `arity`', function(assert) {
+      assert.expect(3);
+
+      var curried = _.curry(fn, 3),
+          expected = [1, 2, 3];
+
+      assert.deepEqual(curried(1)(2, 3), expected);
+      assert.deepEqual(curried(1, 2)(3), expected);
+      assert.deepEqual(curried(1, 2, 3), expected);
+    });
+
+    QUnit.test('should coerce `arity` to an integer', function(assert) {
+      assert.expect(2);
+
+      var values = ['0', 0.6, 'xyz'],
+          expected = lodashStable.map(values, alwaysEmptyArray);
+
+      var actual = lodashStable.map(values, function(arity) {
+        return _.curry(fn, arity)();
+      });
+
+      assert.deepEqual(actual, expected);
+      assert.deepEqual(_.curry(fn, '2')(1)(2), [1, 2]);
+    });
+
+    QUnit.test('should support placeholders', function(assert) {
+      assert.expect(4);
+
+      var curried = _.curry(fn),
+          ph = curried.placeholder;
+
+      assert.deepEqual(curried(1)(ph, 3)(ph, 4)(2), [1, 2, 3, 4]);
+      assert.deepEqual(curried(ph, 2)(1)(ph, 4)(3), [1, 2, 3, 4]);
+      assert.deepEqual(curried(ph, ph, 3)(ph, 2)(ph, 4)(1), [1, 2, 3, 4]);
+      assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), [1, 2, 3, 4]);
+    });
+
+    QUnit.test('should persist placeholders', function(assert) {
+      assert.expect(1);
+
+      var curried = _.curry(fn),
+          ph = curried.placeholder,
+          actual = curried(ph, ph, ph, 'd')('a')(ph)('b')('c');
+
+      assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
+    });
+
+    QUnit.test('should use `_.placeholder` when set', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var curried = _.curry(fn),
+            _ph = _.placeholder = {},
+            ph = curried.placeholder;
+
+        assert.deepEqual(curried(1)(_ph, 3)(ph, 4), [1, ph, 3, 4]);
+        delete _.placeholder;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
+      assert.expect(3);
+
+      var curried = _.curry(fn, 3);
+      assert.deepEqual(curried(1)(2, 3, 4), [1, 2, 3, 4]);
+      assert.deepEqual(curried(1, 2)(3, 4, 5), [1, 2, 3, 4, 5]);
+      assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
+    });
+
+    QUnit.test('should create a function with a `length` of `0`', function(assert) {
+      assert.expect(6);
+
+      lodashStable.times(2, function(index) {
+        var curried = index ? _.curry(fn, 4) : _.curry(fn);
+        assert.strictEqual(curried.length, 0);
+        assert.strictEqual(curried(1).length, 0);
+        assert.strictEqual(curried(1, 2).length, 0);
+      });
+    });
+
+    QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
+      assert.expect(2);
+
+      function Foo(value) {
+        return value && object;
+      }
+
+      var curried = _.curry(Foo),
+          object = {};
+
+      assert.ok(new curried(false) instanceof Foo);
+      assert.strictEqual(new curried(true), object);
+    });
+
+    QUnit.test('should not set a `this` binding', function(assert) {
+      assert.expect(9);
+
+      var fn = function(a, b, c) {
+        var value = this || {};
+        return [value[a], value[b], value[c]];
+      };
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          expected = [1, 2, 3];
+
+      assert.deepEqual(_.curry(_.bind(fn, object), 3)('a')('b')('c'), expected);
+      assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b')('c'), expected);
+      assert.deepEqual(_.curry(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
+
+      assert.deepEqual(_.bind(_.curry(fn), object)('a')('b')('c'), Array(3));
+      assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b')('c'), Array(3));
+      assert.deepEqual(_.bind(_.curry(fn), object)('a', 'b', 'c'), expected);
+
+      object.curried = _.curry(fn);
+      assert.deepEqual(object.curried('a')('b')('c'), Array(3));
+      assert.deepEqual(object.curried('a', 'b')('c'), Array(3));
+      assert.deepEqual(object.curried('a', 'b', 'c'), expected);
+    });
+
+    QUnit.test('should work with partialed methods', function(assert) {
+      assert.expect(2);
+
+      var curried = _.curry(fn),
+          expected = [1, 2, 3, 4];
+
+      var a = _.partial(curried, 1),
+          b = _.bind(a, null, 2),
+          c = _.partialRight(b, 4),
+          d = _.partialRight(b(3), 4);
+
+      assert.deepEqual(c(3), expected);
+      assert.deepEqual(d(), expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.curryRight');
+
+  (function() {
+    function fn(a, b, c, d) {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should curry based on the number of arguments given', function(assert) {
+      assert.expect(3);
+
+      var curried = _.curryRight(fn),
+          expected = [1, 2, 3, 4];
+
+      assert.deepEqual(curried(4)(3)(2)(1), expected);
+      assert.deepEqual(curried(3, 4)(1, 2), expected);
+      assert.deepEqual(curried(1, 2, 3, 4), expected);
+    });
+
+    QUnit.test('should allow specifying `arity`', function(assert) {
+      assert.expect(3);
+
+      var curried = _.curryRight(fn, 3),
+          expected = [1, 2, 3];
+
+      assert.deepEqual(curried(3)(1, 2), expected);
+      assert.deepEqual(curried(2, 3)(1), expected);
+      assert.deepEqual(curried(1, 2, 3), expected);
+    });
+
+    QUnit.test('should coerce `arity` to an integer', function(assert) {
+      assert.expect(2);
+
+      var values = ['0', 0.6, 'xyz'],
+          expected = lodashStable.map(values, alwaysEmptyArray);
+
+      var actual = lodashStable.map(values, function(arity) {
+        return _.curryRight(fn, arity)();
+      });
+
+      assert.deepEqual(actual, expected);
+      assert.deepEqual(_.curryRight(fn, '2')(1)(2), [2, 1]);
+    });
+
+    QUnit.test('should support placeholders', function(assert) {
+      assert.expect(4);
+
+      var curried = _.curryRight(fn),
+          expected = [1, 2, 3, 4],
+          ph = curried.placeholder;
+
+      assert.deepEqual(curried(4)(2, ph)(1, ph)(3), expected);
+      assert.deepEqual(curried(3, ph)(4)(1, ph)(2), expected);
+      assert.deepEqual(curried(ph, ph, 4)(ph, 3)(ph, 2)(1), expected);
+      assert.deepEqual(curried(ph, ph, ph, 4)(ph, ph, 3)(ph, 2)(1), expected);
+    });
+
+    QUnit.test('should persist placeholders', function(assert) {
+      assert.expect(1);
+
+      var curried = _.curryRight(fn),
+          ph = curried.placeholder,
+          actual = curried('a', ph, ph, ph)('b')(ph)('c')('d');
+
+      assert.deepEqual(actual, ['a', 'b', 'c', 'd']);
+    });
+
+    QUnit.test('should use `_.placeholder` when set', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var curried = _.curryRight(fn),
+            _ph = _.placeholder = {},
+            ph = curried.placeholder;
+
+        assert.deepEqual(curried(4)(2, _ph)(1, ph), [1, 2, ph, 4]);
+        delete _.placeholder;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should provide additional arguments after reaching the target arity', function(assert) {
+      assert.expect(3);
+
+      var curried = _.curryRight(fn, 3);
+      assert.deepEqual(curried(4)(1, 2, 3), [1, 2, 3, 4]);
+      assert.deepEqual(curried(4, 5)(1, 2, 3), [1, 2, 3, 4, 5]);
+      assert.deepEqual(curried(1, 2, 3, 4, 5, 6), [1, 2, 3, 4, 5, 6]);
+    });
+
+    QUnit.test('should create a function with a `length` of `0`', function(assert) {
+      assert.expect(6);
+
+      lodashStable.times(2, function(index) {
+        var curried = index ? _.curryRight(fn, 4) : _.curryRight(fn);
+        assert.strictEqual(curried.length, 0);
+        assert.strictEqual(curried(4).length, 0);
+        assert.strictEqual(curried(3, 4).length, 0);
+      });
+    });
+
+    QUnit.test('should ensure `new curried` is an instance of `func`', function(assert) {
+      assert.expect(2);
+
+      function Foo(value) {
+        return value && object;
+      }
+
+      var curried = _.curryRight(Foo),
+          object = {};
+
+      assert.ok(new curried(false) instanceof Foo);
+      assert.strictEqual(new curried(true), object);
+    });
+
+    QUnit.test('should not set a `this` binding', function(assert) {
+      assert.expect(9);
+
+      var fn = function(a, b, c) {
+        var value = this || {};
+        return [value[a], value[b], value[c]];
+      };
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          expected = [1, 2, 3];
+
+      assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('c')('b')('a'), expected);
+      assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('b', 'c')('a'), expected);
+      assert.deepEqual(_.curryRight(_.bind(fn, object), 3)('a', 'b', 'c'), expected);
+
+      assert.deepEqual(_.bind(_.curryRight(fn), object)('c')('b')('a'), Array(3));
+      assert.deepEqual(_.bind(_.curryRight(fn), object)('b', 'c')('a'), Array(3));
+      assert.deepEqual(_.bind(_.curryRight(fn), object)('a', 'b', 'c'), expected);
+
+      object.curried = _.curryRight(fn);
+      assert.deepEqual(object.curried('c')('b')('a'), Array(3));
+      assert.deepEqual(object.curried('b', 'c')('a'), Array(3));
+      assert.deepEqual(object.curried('a', 'b', 'c'), expected);
+    });
+
+    QUnit.test('should work with partialed methods', function(assert) {
+      assert.expect(2);
+
+      var curried = _.curryRight(fn),
+          expected = [1, 2, 3, 4];
+
+      var a = _.partialRight(curried, 4),
+          b = _.partialRight(a, 3),
+          c = _.bind(b, null, 1),
+          d = _.partial(b(2), 1);
+
+      assert.deepEqual(c(2), expected);
+      assert.deepEqual(d(), expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('curry methods');
+
+  lodashStable.each(['curry', 'curryRight'], function(methodName) {
+    var func = _[methodName],
+        fn = function(a, b) { return slice.call(arguments); },
+        isCurry = methodName == 'curry';
+
+    QUnit.test('`_.' + methodName + '` should not error on functions with the same name as lodash methods', function(assert) {
+      assert.expect(1);
+
+      function run(a, b) {
+        return a + b;
+      }
+
+      var curried = func(run);
+
+      try {
+        var actual = curried(1)(2);
+      } catch (e) {}
+
+      assert.strictEqual(actual, 3);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work for function names that shadow those on `Object.prototype`', function(assert) {
+      assert.expect(1);
+
+      var curried = _.curry(function hasOwnProperty(a, b, c) {
+        return [a, b, c];
+      });
+
+      var expected = [1, 2, 3];
+
+      assert.deepEqual(curried(1)(2)(3), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(2);
+
+      var array = [fn, fn, fn],
+          object = { 'a': fn, 'b': fn, 'c': fn };
+
+      lodashStable.each([array, object], function(collection) {
+        var curries = lodashStable.map(collection, func),
+            expected = lodashStable.map(collection, lodashStable.constant(isCurry ? ['a', 'b'] : ['b', 'a']));
+
+        var actual = lodashStable.map(curries, function(curried) {
+          return curried('a')('b');
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.debounce');
+
+  (function() {
+    QUnit.test('should debounce a function', function(assert) {
+      assert.expect(6);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var debounced = _.debounce(function(value) {
+        ++callCount;
+        return value;
+      }, 32);
+
+      var actual = [debounced(0), debounced(1), debounced(2)];
+      assert.deepEqual(actual, [undefined, undefined, undefined]);
+      assert.strictEqual(callCount, 0);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+
+        var actual = [debounced(3), debounced(4), debounced(5)];
+        assert.deepEqual(actual, [2, 2, 2]);
+        assert.strictEqual(callCount, 1);
+      }, 128);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        done();
+      }, 256);
+    });
+
+    QUnit.test('subsequent debounced calls return the last `func` result', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var debounced = _.debounce(identity, 32);
+      debounced('x');
+
+      setTimeout(function() {
+        assert.notEqual(debounced('y'), 'y');
+      }, 64);
+
+      setTimeout(function() {
+        assert.notEqual(debounced('z'), 'z');
+        done();
+      }, 128);
+    });
+
+    QUnit.test('should not immediately call `func` when `wait` is `0`', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          debounced = _.debounce(function() { ++callCount; }, 0);
+
+      debounced();
+      debounced();
+      assert.strictEqual(callCount, 0);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+        done();
+      }, 5);
+    });
+
+    QUnit.test('should apply default options', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          debounced = _.debounce(function() { callCount++; }, 32, {});
+
+      debounced();
+      assert.strictEqual(callCount, 0);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('should support a `leading` option', function(assert) {
+      assert.expect(4);
+
+      var done = assert.async();
+
+      var callCounts = [0, 0];
+
+      var withLeading = _.debounce(function() {
+        callCounts[0]++;
+      }, 32, { 'leading': true });
+
+      var withLeadingAndTrailing = _.debounce(function() {
+        callCounts[1]++;
+      }, 32, { 'leading': true });
+
+      withLeading();
+      assert.strictEqual(callCounts[0], 1);
+
+      withLeadingAndTrailing();
+      withLeadingAndTrailing();
+      assert.strictEqual(callCounts[1], 1);
+
+      setTimeout(function() {
+        assert.deepEqual(callCounts, [1, 2]);
+
+        withLeading();
+        assert.strictEqual(callCounts[0], 2);
+
+        done();
+      }, 64);
+    });
+
+    QUnit.test('subsequent leading debounced calls return the last `func` result', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var debounced = _.debounce(identity, 32, { 'leading': true, 'trailing': false }),
+          result = [debounced('x'), debounced('y')];
+
+      assert.deepEqual(result, ['x', 'x']);
+
+      setTimeout(function() {
+        var result = [debounced('a'), debounced('b')];
+        assert.deepEqual(result, ['a', 'a']);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('should support a `trailing` option', function(assert) {
+      assert.expect(4);
+
+      var done = assert.async();
+
+      var withCount = 0,
+          withoutCount = 0;
+
+      var withTrailing = _.debounce(function() {
+        withCount++;
+      }, 32, { 'trailing': true });
+
+      var withoutTrailing = _.debounce(function() {
+        withoutCount++;
+      }, 32, { 'trailing': false });
+
+      withTrailing();
+      assert.strictEqual(withCount, 0);
+
+      withoutTrailing();
+      assert.strictEqual(withoutCount, 0);
+
+      setTimeout(function() {
+        assert.strictEqual(withCount, 1);
+        assert.strictEqual(withoutCount, 0);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('should support a `maxWait` option', function(assert) {
+      assert.expect(4);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var debounced = _.debounce(function(value) {
+        ++callCount;
+        return value;
+      }, 32, { 'maxWait': 64 });
+
+      debounced();
+      debounced();
+      assert.strictEqual(callCount, 0);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+        debounced();
+        debounced();
+        assert.strictEqual(callCount, 1);
+      }, 128);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        done();
+      }, 256);
+    });
+
+    QUnit.test('should support `maxWait` in a tight loop', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var limit = (argv || isPhantom) ? 1000 : 320,
+          withCount = 0,
+          withoutCount = 0;
+
+      var withMaxWait = _.debounce(function() {
+        withCount++;
+      }, 64, { 'maxWait': 128 });
+
+      var withoutMaxWait = _.debounce(function() {
+        withoutCount++;
+      }, 96);
+
+      var start = +new Date;
+      while ((new Date - start) < limit) {
+        withMaxWait();
+        withoutMaxWait();
+      }
+      var actual = [Boolean(withoutCount), Boolean(withCount)];
+      setTimeout(function() {
+        assert.deepEqual(actual, [false, true]);
+        done();
+      }, 1);
+    });
+
+    QUnit.test('should queue a trailing call for subsequent debounced calls after `maxWait`', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var debounced = _.debounce(function() {
+        ++callCount;
+      }, 64, { 'maxWait': 64 });
+
+      debounced();
+
+      lodashStable.times(20, function(index) {
+        setTimeout(debounced, 54 + index);
+      });
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        done();
+      }, 160);
+    });
+
+    QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var debounced = _.debounce(function() {
+        callCount++;
+      }, 32, { 'maxWait': 64 });
+
+      debounced();
+
+      setTimeout(function() {
+        debounced();
+        assert.strictEqual(callCount, 1);
+      }, 128);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        done();
+      }, 192);
+    });
+
+    QUnit.test('should invoke the trailing call with the correct arguments and `this` binding', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var actual,
+          callCount = 0,
+          object = {};
+
+      var debounced = _.debounce(function(value) {
+        actual = [this];
+        push.apply(actual, arguments);
+        return ++callCount != 2;
+      }, 32, { 'leading': true, 'maxWait': 64 });
+
+      while (true) {
+        if (!debounced.call(object, 'a')) {
+          break;
+        }
+      }
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        assert.deepEqual(actual, [object, 'a']);
+        done();
+      }, 64);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.deburr');
+
+  (function() {
+    QUnit.test('should convert latin-1 supplementary letters to basic latin', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(burredLetters, _.deburr);
+      assert.deepEqual(actual, deburredLetters);
+    });
+
+    QUnit.test('should not deburr latin-1 mathematical operators', function(assert) {
+      assert.expect(1);
+
+      var operators = ['\xd7', '\xf7'],
+          actual = lodashStable.map(operators, _.deburr);
+
+      assert.deepEqual(actual, operators);
+    });
+
+    QUnit.test('should deburr combining diacritical marks', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(comboMarks, lodashStable.constant('ei'));
+
+      var actual = lodashStable.map(comboMarks, function(chr) {
+        return _.deburr('e' + chr + 'i');
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.defaults');
+
+  (function() {
+    QUnit.test('should assign source properties if missing on `object`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.defaults({ 'a': 1 }, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 });
+    });
+
+    QUnit.test('should accept multiple sources', function(assert) {
+      assert.expect(2);
+
+      var expected = { 'a': 1, 'b': 2, 'c': 3 };
+      assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3 }, { 'c': 3 }), expected);
+      assert.deepEqual(_.defaults({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 3 }, { 'c': 2 }), expected);
+    });
+
+    QUnit.test('should not overwrite `null` values', function(assert) {
+      assert.expect(1);
+
+      var actual = _.defaults({ 'a': null }, { 'a': 1 });
+      assert.strictEqual(actual.a, null);
+    });
+
+    QUnit.test('should overwrite `undefined` values', function(assert) {
+      assert.expect(1);
+
+      var actual = _.defaults({ 'a': undefined }, { 'a': 1 });
+      assert.strictEqual(actual.a, 1);
+    });
+
+    QUnit.test('should assign properties that shadow those on `Object.prototype`', function(assert) {
+      assert.expect(2);
+
+      var object = {
+        'constructor': objectProto.constructor,
+        'hasOwnProperty': objectProto.hasOwnProperty,
+        'isPrototypeOf': objectProto.isPrototypeOf,
+        'propertyIsEnumerable': objectProto.propertyIsEnumerable,
+        'toLocaleString': objectProto.toLocaleString,
+        'toString': objectProto.toString,
+        'valueOf': objectProto.valueOf
+      };
+
+      var source = {
+        'constructor': 1,
+        'hasOwnProperty': 2,
+        'isPrototypeOf': 3,
+        'propertyIsEnumerable': 4,
+        'toLocaleString': 5,
+        'toString': 6,
+        'valueOf': 7
+      };
+
+      assert.deepEqual(_.defaults({}, source), source);
+      assert.deepEqual(_.defaults({}, object, source), object);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.defaultsDeep');
+
+  (function() {
+    QUnit.test('should deep assign source properties if missing on `object`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': 2 }, 'd': 4 },
+          source = { 'a': { 'b': 1, 'c': 3 }, 'e': 5 },
+          expected = { 'a': { 'b': 2, 'c': 3 }, 'd': 4, 'e': 5 };
+
+      assert.deepEqual(_.defaultsDeep(object, source), expected);
+    });
+
+    QUnit.test('should accept multiple sources', function(assert) {
+      assert.expect(2);
+
+      var source1 = { 'a': { 'b': 3 } },
+          source2 = { 'a': { 'c': 3 } },
+          source3 = { 'a': { 'b': 3, 'c': 3 } },
+          source4 = { 'a': { 'c': 4 } },
+          expected = { 'a': { 'b': 2, 'c': 3 } };
+
+      assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source1, source2), expected);
+      assert.deepEqual(_.defaultsDeep({ 'a': { 'b': 2 } }, source3, source4), expected);
+    });
+
+    QUnit.test('should not overwrite `null` values', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': null } },
+          source = { 'a': { 'b': 2 } },
+          actual = _.defaultsDeep(object, source);
+
+      assert.strictEqual(actual.a.b, null);
+    });
+
+    QUnit.test('should not overwrite regexp values', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': /x/ } },
+          source = { 'a': { 'b': /y/ } },
+          actual = _.defaultsDeep(object, source);
+
+      assert.deepEqual(actual.a.b, /x/);
+    });
+
+    QUnit.test('should not convert function properties to objects', function(assert) {
+      assert.expect(2);
+
+      var actual = _.defaultsDeep({}, { 'a': noop });
+      assert.strictEqual(actual.a, noop);
+
+      actual = _.defaultsDeep({}, { 'a': { 'b': noop } });
+      assert.strictEqual(actual.a.b, noop);
+    });
+
+    QUnit.test('should overwrite `undefined` values', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': undefined } },
+          source = { 'a': { 'b': 2 } },
+          actual = _.defaultsDeep(object, source);
+
+      assert.strictEqual(actual.a.b, 2);
+    });
+
+    QUnit.test('should merge sources containing circular references', function(assert) {
+      assert.expect(2);
+
+      var object = {
+        'foo': { 'b': { 'c': { 'd': {} } } },
+        'bar': { 'a': 2 }
+      };
+
+      var source = {
+        'foo': { 'b': { 'c': { 'd': {} } } },
+        'bar': {}
+      };
+
+      object.foo.b.c.d = object;
+      source.foo.b.c.d = source;
+      source.bar.b = source.foo.b;
+
+      var actual = _.defaultsDeep(object, source);
+
+      assert.strictEqual(actual.bar.b, actual.foo.b);
+      assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
+    });
+
+    QUnit.test('should not modify sources', function(assert) {
+      assert.expect(3);
+
+      var source1 = { 'a': 1, 'b': { 'c': 2 } },
+          source2 = { 'b': { 'c': 3, 'd': 3 } },
+          actual = _.defaultsDeep({}, source1, source2);
+
+      assert.deepEqual(actual, { 'a': 1, 'b': { 'c': 2, 'd': 3 } });
+      assert.deepEqual(source1, { 'a': 1, 'b': { 'c': 2 } });
+      assert.deepEqual(source2, { 'b': { 'c': 3, 'd': 3 } });
+    });
+
+    QUnit.test('should not attempt a merge of a string into an array', function(assert) {
+      assert.expect(1);
+
+      var actual = _.defaultsDeep({ 'a': ['abc'] }, { 'a': 'abc' });
+      assert.deepEqual(actual, { 'a': ['abc'] });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.defer');
+
+  (function() {
+    QUnit.test('should defer `func` execution', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var pass = false;
+      _.defer(function() { pass = true; });
+
+      setTimeout(function() {
+        assert.ok(pass);
+        done();
+      }, 32);
+    });
+
+    QUnit.test('should provide additional arguments to `func`', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var args;
+
+      _.defer(function() {
+        args = slice.call(arguments);
+      }, 1, 2);
+
+      setTimeout(function() {
+        assert.deepEqual(args, [1, 2]);
+        done();
+      }, 32);
+    });
+
+    QUnit.test('should be cancelable', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var pass = true;
+
+      var timerId = _.defer(function() {
+        pass = false;
+      });
+
+      clearTimeout(timerId);
+
+      setTimeout(function() {
+        assert.ok(pass);
+        done();
+      }, 32);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.delay');
+
+  (function() {
+    QUnit.test('should delay `func` execution', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var pass = false;
+      _.delay(function() { pass = true; }, 32);
+
+      setTimeout(function() {
+        assert.notOk(pass);
+      }, 1);
+
+      setTimeout(function() {
+        assert.ok(pass);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('should provide additional arguments to `func`', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var args;
+
+      _.delay(function() {
+        args = slice.call(arguments);
+      }, 32, 1, 2);
+
+      setTimeout(function() {
+        assert.deepEqual(args, [1, 2]);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('should use a default `wait` of `0`', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var pass = false;
+
+      _.delay(function() {
+        pass = true;
+      });
+
+      assert.notOk(pass);
+
+      setTimeout(function() {
+        assert.ok(pass);
+        done();
+      }, 0);
+    });
+
+    QUnit.test('should be cancelable', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var pass = true;
+
+      var timerId = _.delay(function() {
+        pass = false;
+      }, 32);
+
+      clearTimeout(timerId);
+
+      setTimeout(function() {
+        assert.ok(pass);
+        done();
+      }, 64);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('difference methods');
+
+  lodashStable.each(['difference', 'differenceBy', 'differenceWith'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return the difference of the given arrays', function(assert) {
+      assert.expect(2);
+
+      var actual = func([1, 2, 3, 4, 5], [5, 2, 10]);
+      assert.deepEqual(actual, [1, 3, 4]);
+
+      actual = func([1, 2, 3, 4, 5], [5, 2, 10], [8, 4]);
+      assert.deepEqual(actual, [1, 3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      var array = [-0, 0];
+
+      var actual = lodashStable.map(array, function(value) {
+        return func(array, [value]);
+      });
+
+      assert.deepEqual(actual, [[], []]);
+
+      actual = lodashStable.map(func([-0, 1], [1]), lodashStable.toString);
+      assert.deepEqual(actual, ['0']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func([1, NaN, 3], [NaN, 5, NaN]), [1, 3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
+      assert.expect(1);
+
+      var array1 = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+          array2 = lodashStable.range(LARGE_ARRAY_SIZE),
+          a = {},
+          b = {},
+          c = {};
+
+      array1.push(a, b, c);
+      array2.push(b, c, a);
+
+      assert.deepEqual(func(array1, array2), [LARGE_ARRAY_SIZE]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      var array = [-0, 0];
+
+      var actual = lodashStable.map(array, function(value) {
+        var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
+        return func(array, largeArray);
+      });
+
+      assert.deepEqual(actual, [[], []]);
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysOne);
+      actual = lodashStable.map(func([-0, 1], largeArray), lodashStable.toString);
+      assert.deepEqual(actual, ['0']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
+      assert.expect(1);
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
+      assert.deepEqual(func([1, NaN, 3], largeArray), [1, 3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
+      assert.expect(1);
+
+      var object1 = {},
+          object2 = {},
+          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object1));
+
+      assert.deepEqual(func([object1, object2], largeArray), [object2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore values that are not array-like', function(assert) {
+      assert.expect(3);
+
+      var array = [1, null, 3];
+
+      assert.deepEqual(func(args, 3, { '0': 1 }), [1, 2, 3]);
+      assert.deepEqual(func(null, array, 1), []);
+      assert.deepEqual(func(array, args, null), [null]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.differenceBy');
+
+  (function() {
+    QUnit.test('should accept an `iteratee` argument', function(assert) {
+      assert.expect(2);
+
+      var actual = _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);
+      assert.deepEqual(actual, [3.1, 1.3]);
+
+      actual = _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
+      assert.deepEqual(actual, [{ 'x': 2 }]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [4.4]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.differenceWith');
+
+  (function() {
+    QUnit.test('should work with a `comparator` argument', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
+          actual = _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], lodashStable.isEqual);
+
+      assert.deepEqual(actual, [objects[1]]);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var array = [-0, 1],
+          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysOne),
+          others = [[1], largeArray],
+          expected = lodashStable.map(others, lodashStable.constant(['-0']));
+
+      var actual = lodashStable.map(others, function(other) {
+        return lodashStable.map(_.differenceWith(array, other, lodashStable.eq), lodashStable.toString);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.divide');
+
+  (function() {
+    QUnit.test('should divide two numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.divide(6, 4), 1.5);
+      assert.strictEqual(_.divide(-6, 4), -1.5);
+      assert.strictEqual(_.divide(-6, -4), 1.5);
+    });
+
+    QUnit.test('should coerce arguments to numbers', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.divide('6', '4'), 1.5);
+      assert.deepEqual(_.divide('x', 'y'), NaN);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.drop');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should drop the first two elements', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.drop(array, 2), [3]);
+    });
+
+    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? [2, 3] : array;
+      });
+
+      var actual = lodashStable.map(falsey, function(n) {
+        return _.drop(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return all elements when `n` < `1`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([0, -1, -Infinity], function(n) {
+        assert.deepEqual(_.drop(array, n), array);
+      });
+    });
+
+    QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
+        assert.deepEqual(_.drop(array, n), []);
+      });
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.drop(array, 1.6), [2, 3]);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.drop);
+
+      assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
+            predicate = function(value) { values.push(value); return isEven(value); },
+            values = [],
+            actual = _(array).drop(2).drop().value();
+
+        assert.deepEqual(actual, array.slice(3));
+
+        actual = _(array).filter(predicate).drop(2).drop().value();
+        assert.deepEqual(values, array);
+        assert.deepEqual(actual, _.drop(_.drop(_.filter(array, predicate), 2)));
+
+        actual = _(array).drop(2).dropRight().drop().dropRight(2).value();
+        assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(array, 2))), 2));
+
+        values = [];
+
+        actual = _(array).drop().filter(predicate).drop(2).dropRight().drop().dropRight(2).value();
+        assert.deepEqual(values, array.slice(1));
+        assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2));
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.dropRight');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should drop the last two elements', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropRight(array, 2), [1]);
+    });
+
+    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? [1, 2] : array;
+      });
+
+      var actual = lodashStable.map(falsey, function(n) {
+        return _.dropRight(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return all elements when `n` < `1`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([0, -1, -Infinity], function(n) {
+        assert.deepEqual(_.dropRight(array, n), array);
+      });
+    });
+
+    QUnit.test('should return an empty array when `n` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
+        assert.deepEqual(_.dropRight(array, n), []);
+      });
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropRight(array, 1.6), [1, 2]);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.dropRight);
+
+      assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
+            predicate = function(value) { values.push(value); return isEven(value); },
+            values = [],
+            actual = _(array).dropRight(2).dropRight().value();
+
+        assert.deepEqual(actual, array.slice(0, -3));
+
+        actual = _(array).filter(predicate).dropRight(2).dropRight().value();
+        assert.deepEqual(values, array);
+        assert.deepEqual(actual, _.dropRight(_.dropRight(_.filter(array, predicate), 2)));
+
+        actual = _(array).dropRight(2).drop().dropRight().drop(2).value();
+        assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(array, 2))), 2));
+
+        values = [];
+
+        actual = _(array).dropRight().filter(predicate).dropRight(2).drop().dropRight().drop(2).value();
+        assert.deepEqual(values, array.slice(0, -1));
+        assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2));
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.dropRightWhile');
+
+  (function() {
+    var array = [1, 2, 3, 4];
+
+    var objects = [
+      { 'a': 0, 'b': 0 },
+      { 'a': 1, 'b': 1 },
+      { 'a': 2, 'b': 2 }
+    ];
+
+    QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
+      assert.expect(1);
+
+      var actual = _.dropRightWhile(array, function(n) {
+        return n > 2;
+      });
+
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.dropRightWhile(array, function() {
+        args = slice.call(arguments);
+      });
+
+      assert.deepEqual(args, [4, 3, array]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropRightWhile(objects, { 'b': 2 }), objects.slice(0, 2));
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropRightWhile(objects, ['b', 2]), objects.slice(0, 2));
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropRightWhile(objects, 'b'), objects.slice(0, 1));
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _(array).dropRightWhile(function(n) {
+          return n > 2;
+        });
+
+        assert.ok(wrapped instanceof _);
+        assert.deepEqual(wrapped.value(), [1, 2]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.dropWhile');
+
+  (function() {
+    var array = [1, 2, 3, 4];
+
+    var objects = [
+      { 'a': 2, 'b': 2 },
+      { 'a': 1, 'b': 1 },
+      { 'a': 0, 'b': 0 }
+    ];
+
+    QUnit.test('should drop elements while `predicate` returns truthy', function(assert) {
+      assert.expect(1);
+
+      var actual = _.dropWhile(array, function(n) {
+        return n < 3;
+      });
+
+      assert.deepEqual(actual, [3, 4]);
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.dropWhile(array, function() {
+        args = slice.call(arguments);
+      });
+
+      assert.deepEqual(args, [1, 0, array]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropWhile(objects, { 'b': 2 }), objects.slice(1));
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropWhile(objects, ['b', 2]), objects.slice(1));
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.dropWhile(objects, 'b'), objects.slice(2));
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3),
+            predicate = function(n) { return n < 3; },
+            expected = _.dropWhile(array, predicate),
+            wrapped = _(array).dropWhile(predicate);
+
+        assert.deepEqual(wrapped.value(), expected);
+        assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
+        assert.strictEqual(wrapped.last(), _.last(expected));
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence with `drop`', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 3);
+
+        var actual = _(array)
+          .dropWhile(function(n) { return n == 1; })
+          .drop()
+          .dropWhile(function(n) { return n == 3; })
+          .value();
+
+        assert.deepEqual(actual, array.slice(3));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.endsWith');
+
+  (function() {
+    var string = 'abc';
+
+    QUnit.test('should return `true` if a string ends with `target`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.endsWith(string, 'c'), true);
+    });
+
+    QUnit.test('should return `false` if a string does not end with `target`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.endsWith(string, 'b'), false);
+    });
+
+    QUnit.test('should work with a `position` argument', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.endsWith(string, 'b', 2), true);
+    });
+
+    QUnit.test('should work with `position` >= `string.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
+        assert.strictEqual(_.endsWith(string, 'c', position), true);
+      });
+    });
+
+    QUnit.test('should treat falsey `position` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysTrue);
+
+      var actual = lodashStable.map(falsey, function(position) {
+        return _.endsWith(string, position === undefined ? 'c' : '', position);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat a negative `position` as `0`', function(assert) {
+      assert.expect(6);
+
+      lodashStable.each([-1, -3, -Infinity], function(position) {
+        assert.ok(lodashStable.every(string, function(chr) {
+          return _.endsWith(string, chr, position) === false;
+        }));
+        assert.strictEqual(_.endsWith(string, '', position), true);
+      });
+    });
+
+    QUnit.test('should coerce `position` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.endsWith(string, 'ab', 2.2), true);
+    });
+
+    QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
+      assert.expect(1);
+
+      assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
+        return _.endsWith(string, '', position, true);
+      }));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.eq');
+
+  (function() {
+    QUnit.test('should perform a `SameValueZero` comparison of two values', function(assert) {
+      assert.expect(11);
+
+      assert.strictEqual(_.eq(), true);
+      assert.strictEqual(_.eq(undefined), true);
+      assert.strictEqual(_.eq(0, -0), true);
+      assert.strictEqual(_.eq(NaN, NaN), true);
+      assert.strictEqual(_.eq(1, 1), true);
+
+      assert.strictEqual(_.eq(null, undefined), false);
+      assert.strictEqual(_.eq(1, Object(1)), false);
+      assert.strictEqual(_.eq(1, '1'), false);
+      assert.strictEqual(_.eq(1, '1'), false);
+
+      var object = { 'a': 1 };
+      assert.strictEqual(_.eq(object, object), true);
+      assert.strictEqual(_.eq(object, { 'a': 1 }), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.escape');
+
+  (function() {
+    var escaped = '&amp;&lt;&gt;&quot;&#39;&#96;\/',
+        unescaped = '&<>"\'`\/';
+
+    escaped += escaped;
+    unescaped += unescaped;
+
+    QUnit.test('should escape values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.escape(unescaped), escaped);
+    });
+
+    QUnit.test('should not escape the "/" character', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.escape('/'), '/');
+    });
+
+    QUnit.test('should handle strings with nothing to escape', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.escape('abc'), 'abc');
+    });
+
+    QUnit.test('should escape the same characters unescaped by `_.unescape`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.escape(_.unescape(escaped)), escaped);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.escapeRegExp');
+
+  (function() {
+    var escaped = '\\^\\$\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|\\\\',
+        unescaped = '^$.*+?()[]{}|\\';
+
+    QUnit.test('should escape values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.escapeRegExp(unescaped + unescaped), escaped + escaped);
+    });
+
+    QUnit.test('should handle strings with nothing to escape', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.escapeRegExp('abc'), 'abc');
+    });
+
+    QUnit.test('should return an empty string for empty values', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined, ''],
+          expected = lodashStable.map(values, alwaysEmptyString);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.escapeRegExp(value) : _.escapeRegExp();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.every');
+
+  (function() {
+    QUnit.test('should return `true` if `predicate` returns truthy for all elements', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(lodashStable.every([true, 1, 'a'], identity), true);
+    });
+
+    QUnit.test('should return `true` for empty collections', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, alwaysTrue);
+
+      var actual = lodashStable.map(empties, function(value) {
+        try {
+          return _.every(value, identity);
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` as soon as `predicate` returns falsey', function(assert) {
+      assert.expect(2);
+
+      var count = 0;
+
+      assert.strictEqual(_.every([true, null, true], function(value) {
+        count++;
+        return value;
+      }), false);
+
+      assert.strictEqual(count, 2);
+    });
+
+    QUnit.test('should work with collections of `undefined` values (test in IE < 9)', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.every([undefined, undefined, undefined], identity), false);
+    });
+
+    QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var array = [0];
+        return index ? _.every(array, value) : _.every(array);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(values, alwaysTrue);
+      actual = lodashStable.map(values, function(value, index) {
+        var array = [1];
+        return index ? _.every(array, value) : _.every(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
+      assert.strictEqual(_.every(objects, 'a'), false);
+      assert.strictEqual(_.every(objects, 'b'), true);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(2);
+
+      var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
+      assert.strictEqual(_.every(objects, { 'a': 0 }), true);
+      assert.strictEqual(_.every(objects, { 'b': 1 }), false);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map([[1]], _.every);
+      assert.deepEqual(actual, [true]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('strict mode checks');
+
+  lodashStable.each(['assign', 'assignIn', 'bindAll', 'defaults'], function(methodName) {
+    var func = _[methodName],
+        isBindAll = methodName == 'bindAll';
+
+    QUnit.test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', function(assert) {
+      assert.expect(1);
+
+      if (freeze) {
+        var object = freeze({ 'a': undefined, 'b': function() {} }),
+            pass = !isStrict;
+
+        try {
+          func(object, isBindAll ? 'b' : { 'a': 1 });
+        } catch (e) {
+          pass = !pass;
+        }
+        assert.ok(pass);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.fill');
+
+  (function() {
+    QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(_.fill(array, 'a'), ['a', 'a', 'a']);
+    });
+
+    QUnit.test('should use `undefined` for `value` if not given', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          actual = _.fill(array);
+
+      assert.deepEqual(actual, Array(3));
+      assert.ok(lodashStable.every(actual, function(value, index) {
+        return index in actual;
+      }));
+    });
+
+    QUnit.test('should work with a positive `start`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(_.fill(array, 'a', 1), [1, 'a', 'a']);
+    });
+
+    QUnit.test('should work with a `start` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
+        var array = [1, 2, 3];
+        assert.deepEqual(_.fill(array, 'a', start), [1, 2, 3]);
+      });
+    });
+
+    QUnit.test('should treat falsey `start` values as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, lodashStable.constant(['a', 'a', 'a']));
+
+      var actual = lodashStable.map(falsey, function(start) {
+        var array = [1, 2, 3];
+        return _.fill(array, 'a', start);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with a negative `start`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(_.fill(array, 'a', -1), [1, 2, 'a']);
+    });
+
+    QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([-3, -4, -Infinity], function(start) {
+        var array = [1, 2, 3];
+        assert.deepEqual(_.fill(array, 'a', start), ['a', 'a', 'a']);
+      });
+    });
+
+    QUnit.test('should work with `start` >= `end`', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([2, 3], function(start) {
+        var array = [1, 2, 3];
+        assert.deepEqual(_.fill(array, 'a', start, 2), [1, 2, 3]);
+      });
+    });
+
+    QUnit.test('should work with a positive `end`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(_.fill(array, 'a', 0, 1), ['a', 2, 3]);
+    });
+
+    QUnit.test('should work with a `end` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
+        var array = [1, 2, 3];
+        assert.deepEqual(_.fill(array, 'a', 0, end), ['a', 'a', 'a']);
+      });
+    });
+
+    QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? ['a', 'a', 'a'] : [1, 2, 3];
+      });
+
+      var actual = lodashStable.map(falsey, function(end) {
+        var array = [1, 2, 3];
+        return _.fill(array, 'a', 0, end);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with a negative `end`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(_.fill(array, 'a', 0, -1), ['a', 'a', 3]);
+    });
+
+    QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([-3, -4, -Infinity], function(end) {
+        var array = [1, 2, 3];
+        assert.deepEqual(_.fill(array, 'a', 0, end), [1, 2, 3]);
+      });
+    });
+
+    QUnit.test('should coerce `start` and `end` to integers', function(assert) {
+      assert.expect(1);
+
+      var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
+
+      var actual = lodashStable.map(positions, function(pos) {
+        var array = [1, 2, 3];
+        return _.fill.apply(_, [array, 'a'].concat(pos));
+      });
+
+      assert.deepEqual(actual, [['a', 2, 3], ['a', 2, 3], ['a', 2, 3], [1, 'a', 'a'], ['a', 2, 3], [1, 2, 3]]);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2], [3, 4]],
+          actual = lodashStable.map(array, _.fill);
+
+      assert.deepEqual(actual, [[0, 0], [1, 1]]);
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var array = [1, 2, 3],
+            wrapped = _(array).fill('a'),
+            actual = wrapped.value();
+
+        assert.ok(wrapped instanceof _);
+        assert.deepEqual(actual, ['a', 'a', 'a']);
+        assert.strictEqual(actual, array);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.filter');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should return elements `predicate` returns truthy for', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.filter(array, isEven), [2]);
+    });
+
+    QUnit.test('should iterate over an object with numeric keys (test in Mobile Safari 8)', function(assert) {
+      assert.expect(1);
+
+      // Trigger a mobile Safari 8 JIT bug.
+      // See https://github.com/lodash/lodash/issues/799.
+      var counter = 0,
+          object = { '1': 'foo', '8': 'bar', '50': 'baz' };
+
+      lodashStable.times(1000, function(assert) {
+        _.filter([], alwaysTrue);
+      });
+
+      _.filter(object, function() {
+        counter++;
+        return true;
+      });
+
+      assert.strictEqual(counter, 3);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  lodashStable.each(['find', 'findLast', 'findIndex', 'findLastIndex', 'findKey', 'findLastKey'], function(methodName) {
+    QUnit.module('lodash.' + methodName);
+
+    var func = _[methodName];
+
+    (function() {
+      var objects = [
+        { 'a': 0, 'b': 0 },
+        { 'a': 1, 'b': 1 },
+        { 'a': 2, 'b': 2 }
+      ];
+
+      var expected = ({
+        'find': [objects[1], undefined, objects[2], objects[1]],
+        'findLast': [objects[2], undefined, objects[2], objects[2]],
+        'findIndex': [1, -1, 2, 1],
+        'findLastIndex': [2, -1, 2, 2],
+        'findKey': ['1', undefined, '2', '1'],
+        'findLastKey': ['2', undefined, '2', '2']
+      })[methodName];
+
+      QUnit.test('`_.' + methodName + '` should return the found value', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(func(objects, function(object) { return object.a; }), expected[0]);
+      });
+
+      QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` if value is not found', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(func(objects, function(object) { return object.a === 3; }), expected[1]);
+      });
+
+      QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(func(objects, { 'b': 2 }), expected[2]);
+      });
+
+      QUnit.test('`_.' + methodName + '` should work with `_.matchesProperty` shorthands', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(func(objects, ['b', 2]), expected[2]);
+      });
+
+      QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(func(objects, 'b'), expected[3]);
+      });
+
+      QUnit.test('`_.' + methodName + '` should return `' + expected[1] + '` for empty collections', function(assert) {
+        assert.expect(1);
+
+        var emptyValues = lodashStable.endsWith(methodName, 'Index') ? lodashStable.reject(empties, lodashStable.isPlainObject) : empties,
+            expecting = lodashStable.map(emptyValues, lodashStable.constant(expected[1]));
+
+        var actual = lodashStable.map(emptyValues, function(value) {
+          try {
+            return func(value, { 'a': 3 });
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expecting);
+      });
+    }());
+
+    (function() {
+      var array = [1, 2, 3, 4];
+
+      var expected = ({
+        'find': 1,
+        'findLast': 4,
+        'findIndex': 0,
+        'findLastIndex': 3,
+        'findKey': '0',
+        'findLastKey': '3'
+      })[methodName];
+
+      QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          assert.strictEqual(_(array)[methodName](), expected);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          assert.ok(_(array).chain()[methodName]() instanceof _);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should not execute immediately when explicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          var wrapped = _(array).chain()[methodName]();
+          assert.strictEqual(wrapped.__wrapped__, array);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
+        assert.expect(2);
+
+        if (!isNpm) {
+          var largeArray = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
+              smallArray = array;
+
+          lodashStable.times(2, function(index) {
+            var array = index ? largeArray : smallArray,
+                wrapped = _(array).filter(isEven);
+
+            assert.strictEqual(wrapped[methodName](), func(lodashStable.filter(array, isEven)));
+          });
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+    }());
+
+    (function() {
+      var expected = ({
+        'find': 1,
+        'findLast': 2,
+        'findKey': 'a',
+        'findLastKey': 'b'
+      })[methodName];
+
+      if (expected != null) {
+        QUnit.test('`_.' + methodName + '` should work with an object for `collection`', function(assert) {
+          assert.expect(1);
+
+          var actual = func({ 'a': 1, 'b': 2, 'c': 3 }, function(n) {
+            return n < 3;
+          });
+
+          assert.strictEqual(actual, expected);
+        });
+      }
+    }());
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.find and lodash.findLast');
+
+  lodashStable.each(['find', 'findLast'], function(methodName) {
+    var isFind = methodName == 'find';
+
+    QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var findCount = 0,
+            mapCount = 0,
+            array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
+            iteratee = function(value) { mapCount++; return square(value); },
+            predicate = function(value) { findCount++; return isEven(value); },
+            actual = _(array).map(iteratee)[methodName](predicate);
+
+        assert.strictEqual(findCount, isFind ? 2 : 1);
+        assert.strictEqual(mapCount, isFind ? 2 : 1);
+        assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE));
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.flip');
+
+  (function() {
+    function fn() {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should flip arguments provided to `func`', function(assert) {
+      assert.expect(1);
+
+      var flipped = _.flip(fn);
+      assert.deepEqual(flipped('a', 'b', 'c', 'd'), ['d', 'c', 'b', 'a']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.flatMapDepth');
+
+  (function() {
+    var array = [1, [2, [3, [4]], 5]];
+
+    QUnit.test('should use a default `depth` of `1`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.flatMapDepth(array, identity), [1, 2, [3, [4]], 5]);
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([1, 2, [3, [4]], 5]));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.flatMapDepth(array, value) : _.flatMapDepth(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([-1, 0], function(depth) {
+        assert.deepEqual(_.flatMapDepth(array, identity, depth), [1, [2, [3, [4]], 5]]);
+      });
+    });
+
+    QUnit.test('should coerce `depth` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.flatMapDepth(array, identity, 2.2), [1, 2, 3, [4], 5]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('flatMap methods');
+
+  lodashStable.each(['flatMap', 'flatMapDeep', 'flatMapDepth'], function(methodName) {
+    var func = _[methodName],
+        array = [1, 2, 3, 4];
+
+    function duplicate(n) {
+      return [n, n];
+    }
+
+    QUnit.test('`_.' + methodName + '` should map values in `array` to a new flattened array', function(assert) {
+      assert.expect(1);
+
+      var actual = func(array, duplicate),
+          expected = lodashStable.flatten(lodashStable.map(array, duplicate));
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': [1, 2] }, { 'a': [3, 4] }];
+      assert.deepEqual(func(objects, 'a'), array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = [1, 2];
+      }
+      Foo.prototype.b = [3, 4];
+
+      var actual = func(new Foo, identity);
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(2);
+
+      var array = [[1, 2], [3, 4]],
+          object = { 'a': [1, 2], 'b': [3, 4] },
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
+
+      lodashStable.each([array, object], function(collection) {
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? func(collection, value) : func(collection);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should accept a falsey `collection` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyArray);
+
+      var actual = lodashStable.map(falsey, function(collection, index) {
+        try {
+          return index ? func(collection) : func();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat number values for `collection` as empty', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(1), []);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with objects with non-number length properties', function(assert) {
+      assert.expect(1);
+
+      var object = { 'length': [1, 2] };
+      assert.deepEqual(func(object, identity), [1, 2]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.flattenDepth');
+
+  (function() {
+    var array = [1, [2, [3, [4]], 5]];
+
+    QUnit.test('should use a default `depth` of `1`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]);
+    });
+
+    QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([-1, 0], function(depth) {
+        assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]);
+      });
+    });
+
+    QUnit.test('should coerce `depth` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('flatten methods');
+
+  (function() {
+    var args = arguments,
+        array = [1, [2, [3, [4]], 5]];
+
+    QUnit.test('should flatten `arguments` objects', function(assert) {
+      assert.expect(3);
+
+      var array = [args, [args]];
+
+      assert.deepEqual(_.flatten(array), [1, 2, 3, args]);
+      assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]);
+      assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]);
+    });
+
+    QUnit.test('should treat sparse arrays as dense', function(assert) {
+      assert.expect(6);
+
+      var array = [[1, 2, 3], Array(3)],
+          expected = [1, 2, 3];
+
+      expected.push(undefined, undefined, undefined);
+
+      lodashStable.each([_.flatten(array), _.flattenDeep(array), _.flattenDepth(array)], function(actual) {
+        assert.deepEqual(actual, expected);
+        assert.ok('4' in actual);
+      });
+    });
+
+    QUnit.test('should work with extremely large arrays', function(assert) {
+      assert.expect(3);
+
+      lodashStable.times(3, function(index) {
+        var expected = Array(5e5);
+        try {
+          var func = _.flatten;
+          if (index == 1) {
+            func = _.flattenDeep;
+          } else if (index == 2) {
+            func = _.flattenDepth;
+          }
+          assert.deepEqual(func([expected]), expected);
+        } catch (e) {
+          assert.ok(false, e.message);
+        }
+      });
+    });
+
+    QUnit.test('should work with empty arrays', function(assert) {
+      assert.expect(3);
+
+      var array = [[], [[]], [[], [[[]]]]];
+
+      assert.deepEqual(_.flatten(array), [[], [], [[[]]]]);
+      assert.deepEqual(_.flattenDeep(array), []);
+      assert.deepEqual(_.flattenDepth(array, 2), [[[]]]);
+    });
+
+    QUnit.test('should support flattening of nested arrays', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]);
+      assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]);
+      assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]);
+    });
+
+    QUnit.test('should return an empty array for non array-like objects', function(assert) {
+      assert.expect(3);
+
+      var expected = [],
+          nonArray = { 'a': 1 };
+
+      assert.deepEqual(_.flatten(nonArray), expected);
+      assert.deepEqual(_.flattenDeep(nonArray), expected);
+      assert.deepEqual(_.flattenDepth(nonArray, 2), expected);
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var wrapped = _(array),
+            actual = wrapped.flatten();
+
+        assert.ok(actual instanceof _);
+        assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]);
+
+        actual = wrapped.flattenDeep();
+
+        assert.ok(actual instanceof _);
+        assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]);
+
+        actual = wrapped.flattenDepth(2);
+
+        assert.ok(actual instanceof _);
+        assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]);
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('flow methods');
+
+  lodashStable.each(['flow', 'flowRight'], function(methodName) {
+    var func = _[methodName],
+        isFlow = methodName == 'flow';
+
+    QUnit.test('`_.' + methodName + '` should supply each function with the return value of the previous', function(assert) {
+      assert.expect(1);
+
+      var fixed = function(n) { return n.toFixed(1); },
+          combined = isFlow ? func(add, square, fixed) : func(fixed, square, add);
+
+      assert.strictEqual(combined(1, 2), '9.0');
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a new function', function(assert) {
+      assert.expect(1);
+
+      assert.notStrictEqual(func(noop), noop);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an identity function when no arguments are given', function(assert) {
+      assert.expect(6);
+
+      _.times(2, function(index) {
+        try {
+          var combined = index ? func([]) : func();
+          assert.strictEqual(combined('a'), 'a');
+        } catch (e) {
+          assert.ok(false, e.message);
+        }
+        assert.strictEqual(combined.length, 0);
+        assert.notStrictEqual(combined, identity);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a curried function and `_.head`', function(assert) {
+      assert.expect(1);
+
+      var curried = _.curry(identity);
+
+      var combined = isFlow
+        ? func(_.head, curried)
+        : func(curried, _.head);
+
+      assert.strictEqual(combined([1]), 1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support shortcut fusion', function(assert) {
+      assert.expect(6);
+
+      var filterCount,
+          mapCount,
+          array = lodashStable.range(LARGE_ARRAY_SIZE),
+          iteratee = function(value) { mapCount++; return square(value); },
+          predicate = function(value) { filterCount++; return isEven(value); };
+
+      lodashStable.times(2, function(index) {
+        var filter1 = _.filter,
+            filter2 = _.curry(_.rearg(_.ary(_.filter, 2), 1, 0), 2),
+            filter3 = (_.filter = index ? filter2 : filter1, filter2(predicate));
+
+        var map1 = _.map,
+            map2 = _.curry(_.rearg(_.ary(_.map, 2), 1, 0), 2),
+            map3 = (_.map = index ? map2 : map1, map2(iteratee));
+
+        var take1 = _.take,
+            take2 = _.curry(_.rearg(_.ary(_.take, 2), 1, 0), 2),
+            take3 = (_.take = index ? take2 : take1, take2(2));
+
+        var combined = isFlow
+          ? func(map3, filter3, _.compact, take3)
+          : func(take3, _.compact, filter3, map3);
+
+        filterCount = mapCount = 0;
+        assert.deepEqual(combined(array), [4, 16]);
+
+        if (!isNpm && WeakMap && WeakMap.name) {
+          assert.strictEqual(filterCount, 5, 'filterCount');
+          assert.strictEqual(mapCount, 5, 'mapCount');
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+        _.filter = filter1;
+        _.map = map1;
+        _.take = take1;
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with curried functions with placeholders', function(assert) {
+      assert.expect(1);
+
+      var curried = _.curry(_.ary(_.map, 2), 2),
+          getProp = curried(curried.placeholder, 'a'),
+          objects = [{ 'a': 1 }, { 'a': 2 }, { 'a': 1 }];
+
+      var combined = isFlow
+        ? func(getProp, _.uniq)
+        : func(_.uniq, getProp);
+
+      assert.deepEqual(combined(objects), [1, 2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _(noop)[methodName]();
+        assert.ok(wrapped instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.forEach');
+
+  (function() {
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.each, _.forEach);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.forEachRight');
+
+  (function() {
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.eachRight, _.forEachRight);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('forIn methods');
+
+  lodashStable.each(['forIn', 'forInRight'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` iterates over inherited string keyed properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var keys = [];
+      func(new Foo, function(value, key) { keys.push(key); });
+      assert.deepEqual(keys.sort(), ['a', 'b']);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('forOwn methods');
+
+  lodashStable.each(['forOwn', 'forOwnRight'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should iterate over `length` properties', function(assert) {
+      assert.expect(1);
+
+      var object = { '0': 'zero', '1': 'one', 'length': 2 },
+          props = [];
+
+      func(object, function(value, prop) { props.push(prop); });
+      assert.deepEqual(props.sort(), ['0', '1', 'length']);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('iteration methods');
+
+  (function() {
+    var methods = [
+      '_baseEach',
+      'countBy',
+      'every',
+      'filter',
+      'find',
+      'findIndex',
+      'findKey',
+      'findLast',
+      'findLastIndex',
+      'findLastKey',
+      'forEach',
+      'forEachRight',
+      'forIn',
+      'forInRight',
+      'forOwn',
+      'forOwnRight',
+      'groupBy',
+      'keyBy',
+      'map',
+      'mapKeys',
+      'mapValues',
+      'maxBy',
+      'minBy',
+      'omitBy',
+      'partition',
+      'pickBy',
+      'reject',
+      'some'
+    ];
+
+    var arrayMethods = [
+      'findIndex',
+      'findLastIndex',
+      'maxBy',
+      'minBy'
+    ];
+
+    var collectionMethods = [
+      '_baseEach',
+      'countBy',
+      'every',
+      'filter',
+      'find',
+      'findLast',
+      'forEach',
+      'forEachRight',
+      'groupBy',
+      'keyBy',
+      'map',
+      'partition',
+      'reduce',
+      'reduceRight',
+      'reject',
+      'some'
+    ];
+
+    var forInMethods = [
+      'forIn',
+      'forInRight',
+      'omitBy',
+      'pickBy'
+    ];
+
+    var iterationMethods = [
+      '_baseEach',
+      'forEach',
+      'forEachRight',
+      'forIn',
+      'forInRight',
+      'forOwn',
+      'forOwnRight'
+    ];
+
+    var objectMethods = [
+      'findKey',
+      'findLastKey',
+      'forIn',
+      'forInRight',
+      'forOwn',
+      'forOwnRight',
+      'mapKeys',
+      'mapValues',
+      'omitBy',
+      'pickBy'
+    ];
+
+    var rightMethods = [
+      'findLast',
+      'findLastIndex',
+      'findLastKey',
+      'forEachRight',
+      'forInRight',
+      'forOwnRight'
+    ];
+
+    var unwrappedMethods = [
+      'each',
+      'eachRight',
+      'every',
+      'find',
+      'findIndex',
+      'findKey',
+      'findLast',
+      'findLastIndex',
+      'findLastKey',
+      'forEach',
+      'forEachRight',
+      'forIn',
+      'forInRight',
+      'forOwn',
+      'forOwnRight',
+      'max',
+      'maxBy',
+      'min',
+      'minBy',
+      'some'
+    ];
+
+    lodashStable.each(methods, function(methodName) {
+      var array = [1, 2, 3],
+          func = _[methodName],
+          isBy = /(^partition|By)$/.test(methodName),
+          isFind = /^find/.test(methodName),
+          isOmitPick = /^(?:omit|pick)By$/.test(methodName),
+          isSome = methodName == 'some';
+
+      QUnit.test('`_.' + methodName + '` should provide the correct iteratee arguments', function(assert) {
+        assert.expect(1);
+
+        if (func) {
+          var args,
+              expected = [1, 0, array];
+
+          func(array, function() {
+            args || (args = slice.call(arguments));
+          });
+
+          if (lodashStable.includes(rightMethods, methodName)) {
+            expected[0] = 3;
+            expected[1] = 2;
+          }
+          if (lodashStable.includes(objectMethods, methodName)) {
+            expected[1] += '';
+          }
+          if (isBy) {
+            expected.length = isOmitPick ? 2 : 1;
+          }
+          assert.deepEqual(args, expected);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
+        assert.expect(1);
+
+        if (func) {
+          var array = [1];
+          array[2] = 3;
+
+          var expected = lodashStable.includes(objectMethods, methodName)
+            ? [[1, '0', array], [undefined, '1', array], [3, '2', array]]
+            : [[1,  0, array],  [undefined,  1,  array], [3,  2,  array]];
+
+          if (isBy) {
+            expected = lodashStable.map(expected, function(args) {
+              return args.slice(0, isOmitPick ? 2 : 1);
+            });
+          }
+          else if (lodashStable.includes(objectMethods, methodName)) {
+            expected = lodashStable.map(expected, function(args) {
+              args[1] += '';
+              return args;
+            });
+          }
+          if (lodashStable.includes(rightMethods, methodName)) {
+            expected.reverse();
+          }
+          var argsList = [];
+          func(array, function() {
+            argsList.push(slice.call(arguments));
+            return !(isFind || isSome);
+          });
+
+          assert.deepEqual(argsList, expected);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each(lodashStable.difference(methods, objectMethods), function(methodName) {
+      var array = [1, 2, 3],
+          func = _[methodName],
+          isEvery = methodName == 'every';
+
+      array.a = 1;
+
+      QUnit.test('`_.' + methodName + '` should not iterate custom properties on arrays', function(assert) {
+        assert.expect(1);
+
+        if (func) {
+          var keys = [];
+          func(array, function(value, key) {
+            keys.push(key);
+            return isEvery;
+          });
+
+          assert.notOk(lodashStable.includes(keys, 'a'));
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each(lodashStable.difference(methods, unwrappedMethods), function(methodName) {
+      var array = [1, 2, 3],
+          isBaseEach = methodName == '_baseEach';
+
+      QUnit.test('`_.' + methodName + '` should return a wrapped value when implicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!(isBaseEach || isNpm)) {
+          var wrapped = _(array)[methodName](noop);
+          assert.ok(wrapped instanceof _);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each(unwrappedMethods, function(methodName) {
+      var array = [1, 2, 3];
+
+      QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          var actual = _(array)[methodName](noop);
+          assert.notOk(actual instanceof _);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+        assert.expect(2);
+
+        if (!isNpm) {
+          var wrapped = _(array).chain(),
+              actual = wrapped[methodName](noop);
+
+          assert.ok(actual instanceof _);
+          assert.notStrictEqual(actual, wrapped);
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+    });
+
+    lodashStable.each(lodashStable.difference(methods, arrayMethods, forInMethods), function(methodName) {
+      var func = _[methodName];
+
+      QUnit.test('`_.' + methodName + '` iterates over own string keyed properties of objects', function(assert) {
+        assert.expect(1);
+
+        function Foo() {
+          this.a = 1;
+        }
+        Foo.prototype.b = 2;
+
+        if (func) {
+          var values = [];
+          func(new Foo, function(value) { values.push(value); });
+          assert.deepEqual(values, [1]);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each(iterationMethods, function(methodName) {
+      var array = [1, 2, 3],
+          func = _[methodName];
+
+      QUnit.test('`_.' + methodName + '` should return the collection', function(assert) {
+        assert.expect(1);
+
+        if (func) {
+          assert.strictEqual(func(array, Boolean), array);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each(collectionMethods, function(methodName) {
+      var func = _[methodName];
+
+      QUnit.test('`_.' + methodName + '` should use `isArrayLike` to determine whether a value is array-like', function(assert) {
+        assert.expect(3);
+
+        if (func) {
+          var isIteratedAsObject = function(object) {
+            var result = false;
+            func(object, function() { result = true; }, 0);
+            return result;
+          };
+
+          var values = [-1, '1', 1.1, Object(1), MAX_SAFE_INTEGER + 1],
+              expected = lodashStable.map(values, alwaysTrue);
+
+          var actual = lodashStable.map(values, function(length) {
+            return isIteratedAsObject({ 'length': length });
+          });
+
+          var Foo = function(a) {};
+          Foo.a = 1;
+
+          assert.deepEqual(actual, expected);
+          assert.ok(isIteratedAsObject(Foo));
+          assert.notOk(isIteratedAsObject({ 'length': 0 }));
+        }
+        else {
+          skipAssert(assert, 3);
+        }
+      });
+    });
+
+    lodashStable.each(methods, function(methodName) {
+      var func = _[methodName],
+          isFind = /^find/.test(methodName),
+          isSome = methodName == 'some',
+          isReduce = /^reduce/.test(methodName);
+
+      QUnit.test('`_.' + methodName + '` should ignore changes to `array.length`', function(assert) {
+        assert.expect(1);
+
+        if (func) {
+          var count = 0,
+              array = [1];
+
+          func(array, function() {
+            if (++count == 1) {
+              array.push(2);
+            }
+            return !(isFind || isSome);
+          }, isReduce ? array : null);
+
+          assert.strictEqual(count, 1);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each(lodashStable.difference(lodashStable.union(methods, collectionMethods), arrayMethods), function(methodName) {
+      var func = _[methodName],
+          isFind = /^find/.test(methodName),
+          isSome = methodName == 'some',
+          isReduce = /^reduce/.test(methodName);
+
+      QUnit.test('`_.' + methodName + '` should ignore added `object` properties', function(assert) {
+        assert.expect(1);
+
+        if (func) {
+          var count = 0,
+              object = { 'a': 1 };
+
+          func(object, function() {
+            if (++count == 1) {
+              object.b = 2;
+            }
+            return !(isFind || isSome);
+          }, isReduce ? object : null);
+
+          assert.strictEqual(count, 1);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('object assignments');
+
+  lodashStable.each(['assign', 'assignIn', 'defaults', 'merge'], function(methodName) {
+    var func = _[methodName],
+        isAssign = methodName == 'assign',
+        isDefaults = methodName == 'defaults';
+
+    QUnit.test('`_.' + methodName + '` should coerce primitives to objects', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(primitives, function(value) {
+        var object = Object(value);
+        object.a = 1;
+        return object;
+      });
+
+      var actual = lodashStable.map(primitives, function(value) {
+        return func(value, { 'a': 1 });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should assign own ' + (isAssign ? '' : 'and inherited ') + 'string keyed source properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var expected = isAssign ? { 'a': 1 } : { 'a': 1, 'b': 2 };
+      assert.deepEqual(func({}, new Foo), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not error on nullish sources', function(assert) {
+      assert.expect(1);
+
+      try {
+        assert.deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 });
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should create an object when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var source = { 'a': 1 },
+          values = [null, undefined],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        var object = func(value, source);
+        return object !== source && lodashStable.isEqual(object, source);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      actual = lodashStable.map(values, function(value) {
+        return lodashStable.isEqual(func(value), {});
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
+      assert.expect(2);
+
+      var array = [{ 'a': 1 }, { 'b': 2 }, { 'c': 3 }],
+          expected = { 'a': isDefaults ? 0 : 1, 'b': 2, 'c': 3 };
+
+      assert.deepEqual(lodashStable.reduce(array, func, { 'a': 0 }), expected);
+
+      var fn = function() {};
+      fn.a = array[0];
+      fn.b = array[1];
+      fn.c = array[2];
+
+      assert.deepEqual(_.reduce(fn, func, { 'a': 0 }), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not return the existing wrapped value when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _({ 'a': 1 }),
+            actual = wrapped[methodName]({ 'b': 2 });
+
+        assert.notStrictEqual(actual, wrapped);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  lodashStable.each(['assign', 'assignIn', 'merge'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should not treat `object` as `source`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype.a = 1;
+
+      var actual = func(new Foo, { 'b': 2 });
+      assert.notOk(_.has(actual, 'a'));
+    });
+  });
+
+  lodashStable.each(['assign', 'assignIn', 'assignInWith', 'assignWith', 'defaults', 'merge', 'mergeWith'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
+        if (defineProperty) {
+          var object = {},
+              pass = true;
+
+          defineProperty(object, 'a', {
+            'enumerable': true,
+            'configurable': true,
+            'get': lodashStable.constant(value),
+            'set': function() { pass = false; }
+          });
+
+          func(object, { 'a': value });
+          assert.ok(pass);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  });
+
+  lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], function(methodName) {
+    var func = _[methodName],
+        isMergeWith = methodName == 'mergeWith';
+
+    QUnit.test('`_.' + methodName + '` should provide the correct `customizer` arguments', function(assert) {
+      assert.expect(3);
+
+      var args,
+          object = { 'a': 1 },
+          source = { 'a': 2 },
+          expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
+
+      func(object, source, function() {
+        args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
+      });
+
+      assert.deepEqual(args, expected, 'primitive property values');
+
+      args = undefined;
+      object = { 'a': 1 };
+      source = { 'b': 2 };
+      expected = lodashStable.map([undefined, 2, 'b', object, source], lodashStable.cloneDeep);
+
+      func(object, source, function() {
+        args || (args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
+      });
+
+      assert.deepEqual(args, expected, 'missing destination property');
+
+      var argsList = [],
+          objectValue = [1, 2],
+          sourceValue = { 'b': 2 };
+
+      object = { 'a': objectValue };
+      source = { 'a': sourceValue };
+      expected = [lodashStable.map([objectValue, sourceValue, 'a', object, source], lodashStable.cloneDeep)];
+
+      if (isMergeWith) {
+        expected.push(lodashStable.map([undefined, 2, 'b', objectValue, sourceValue], lodashStable.cloneDeep));
+      }
+      func(object, source, function() {
+        argsList.push(lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
+      });
+
+      assert.deepEqual(argsList, expected, 'object property values');
+    });
+
+    QUnit.test('`_.' + methodName + '` should not treat the second argument as a `customizer` callback', function(assert) {
+      assert.expect(2);
+
+      function callback() {}
+      callback.b = 2;
+
+      var actual = func({ 'a': 1 }, callback);
+      assert.deepEqual(actual, { 'a': 1, 'b': 2 });
+
+      actual = func({ 'a': 1 }, callback, { 'c': 3 });
+      assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('exit early');
+
+  lodashStable.each(['_baseEach', 'forEach', 'forEachRight', 'forIn', 'forInRight', 'forOwn', 'forOwnRight', 'transform'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` can exit early when iterating arrays', function(assert) {
+      assert.expect(1);
+
+      if (func) {
+        var array = [1, 2, 3],
+            values = [];
+
+        func(array, function(value, other) {
+          values.push(lodashStable.isArray(value) ? other : value);
+          return false;
+        });
+
+        assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` can exit early when iterating objects', function(assert) {
+      assert.expect(1);
+
+      if (func) {
+        var object = { 'a': 1, 'b': 2, 'c': 3 },
+            values = [];
+
+        func(object, function(value, other) {
+          values.push(lodashStable.isArray(value) ? other : value);
+          return false;
+        });
+
+        assert.strictEqual(values.length, 1);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('`__proto__` property bugs');
+
+  (function() {
+    QUnit.test('internal data objects should work with the `__proto__` key', function(assert) {
+      assert.expect(4);
+
+      var stringLiteral = '__proto__',
+          stringObject = Object(stringLiteral),
+          expected = [stringLiteral, stringObject];
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(count) {
+        return isEven(count) ? stringLiteral : stringObject;
+      });
+
+      assert.deepEqual(_.difference(largeArray, largeArray), []);
+      assert.deepEqual(_.intersection(largeArray, largeArray), expected);
+      assert.deepEqual(_.uniq(largeArray), expected);
+      assert.deepEqual(_.without.apply(_, [largeArray].concat(largeArray)), []);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.fromPairs');
+
+  (function() {
+    QUnit.test('should accept a two dimensional array', function(assert) {
+      assert.expect(1);
+
+      var array = [['a', 1], ['b', 2]],
+          object = { 'a': 1, 'b': 2 },
+          actual = _.fromPairs(array);
+
+      assert.deepEqual(actual, object);
+    });
+
+    QUnit.test('should accept a falsey `array` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyObject);
+
+      var actual = lodashStable.map(falsey, function(array, index) {
+        try {
+          return index ? _.fromPairs(array) : _.fromPairs();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not support deep paths', function(assert) {
+      assert.expect(1);
+
+      var actual = _.fromPairs([['a.b', 1]]);
+      assert.deepEqual(actual, { 'a.b': 1 });
+    });
+
+    QUnit.test('should support consuming the return value of `_.toPairs`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a.b': 1 };
+      assert.deepEqual(_.fromPairs(_.toPairs(object)), object);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
+          return ['key' + index, index];
+        });
+
+        var actual = _(array).fromPairs().map(square).filter(isEven).take().value();
+
+        assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven)));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.functions');
+
+  (function() {
+    QUnit.test('should return the function names of an object', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 'a', 'b': identity, 'c': /x/, 'd': noop },
+          actual = _.functions(object).sort();
+
+      assert.deepEqual(actual, ['b', 'd']);
+    });
+
+    QUnit.test('should not include inherited functions', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = identity;
+        this.b = 'b';
+      }
+      Foo.prototype.c = noop;
+
+      assert.deepEqual(_.functions(new Foo), ['a']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.groupBy');
+
+  (function() {
+    var array = [6.1, 4.2, 6.3];
+
+    QUnit.test('should transform keys by `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.groupBy(array, Math.floor);
+      assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var array = [6, 4, 6],
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant({ '4': [4], '6':  [6, 6] }));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.groupBy(array, value) : _.groupBy(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var actual = _.groupBy(['one', 'two', 'three'], 'length');
+      assert.deepEqual(actual, { '3': ['one', 'two'], '5': ['three'] });
+    });
+
+    QUnit.test('should only add values to own, not inherited, properties', function(assert) {
+      assert.expect(2);
+
+      var actual = _.groupBy(array, function(n) {
+        return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
+      });
+
+      assert.deepEqual(actual.constructor, [4.2]);
+      assert.deepEqual(actual.hasOwnProperty, [6.1, 6.3]);
+    });
+
+    QUnit.test('should work with a number for `iteratee`', function(assert) {
+      assert.expect(2);
+
+      var array = [
+        [1, 'a'],
+        [2, 'a'],
+        [2, 'b']
+      ];
+
+      assert.deepEqual(_.groupBy(array, 0), { '1': [[1, 'a']], '2': [[2, 'a'], [2, 'b']] });
+      assert.deepEqual(_.groupBy(array, 1), { 'a': [[1, 'a'], [2, 'a']], 'b': [[2, 'b']] });
+    });
+
+    QUnit.test('should work with an object for `collection`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.groupBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
+      assert.deepEqual(actual, { '4': [4.2], '6': [6.1, 6.3] });
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
+          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
+          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
+        );
+
+        var iteratee = function(value) { value.push(value[0]); return value; },
+            predicate = function(value) { return isEven(value[0]); },
+            actual = _(array).groupBy().map(iteratee).filter(predicate).take().value();
+
+        assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate)));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.gt');
+
+  (function() {
+    QUnit.test('should return `true` if `value` > `other`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.gt(3, 1), true);
+      assert.strictEqual(_.gt('def', 'abc'), true);
+    });
+
+    QUnit.test('should return `false` if `value` is <= `other`', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.gt(1, 3), false);
+      assert.strictEqual(_.gt(3, 3), false);
+      assert.strictEqual(_.gt('abc', 'def'), false);
+      assert.strictEqual(_.gt('def', 'def'), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.gte');
+
+  (function() {
+    QUnit.test('should return `true` if `value` >= `other`', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.gte(3, 1), true);
+      assert.strictEqual(_.gte(3, 3), true);
+      assert.strictEqual(_.gte('def', 'abc'), true);
+      assert.strictEqual(_.gte('def', 'def'), true);
+    });
+
+    QUnit.test('should return `false` if `value` is less than `other`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.gte(1, 3), false);
+      assert.strictEqual(_.gte('abc', 'def'), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('has methods');
+
+  lodashStable.each(['has', 'hasIn'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        func = _[methodName],
+        isHas = methodName == 'has';
+
+    QUnit.test('`_.' + methodName + '` should check for own properties', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1 };
+
+      lodashStable.each(['a', ['a']], function(path) {
+        assert.strictEqual(func(object, path), true);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not use the `hasOwnProperty` method of the object', function(assert) {
+      assert.expect(1);
+
+      var object = { 'hasOwnProperty': null, 'a': 1 };
+      assert.strictEqual(func(object, 'a'), true);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support deep paths', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(func(object, path), true);
+      });
+
+      lodashStable.each(['a.a', ['a', 'a']], function(path) {
+        assert.strictEqual(func(object, path), false);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `path` to a string', function(assert) {
+      assert.expect(1);
+
+      function fn() {}
+      fn.toString = lodashStable.constant('fn');
+
+      var expected = [1, 1, 2, 2, 3, 3, 4, 4],
+          objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
+          values = [null, undefined, fn, {}];
+
+      var actual = lodashStable.transform(objects, function(result, object, index) {
+        var key = values[index];
+        lodashStable.each([key, [key]], function(path) {
+          var prop = _.property(key);
+          result.push(prop(object));
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func(args, 1), true);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a non-string `path`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3];
+
+      lodashStable.each([1, [1]], function(path) {
+        assert.strictEqual(func(array, path), true);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': 'a', '0': 'b' },
+          props = [-0, Object(-0), 0, Object(0)],
+          expected = lodashStable.map(props, alwaysTrue);
+
+      var actual = lodashStable.map(props, function(key) {
+        return func(object, key);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a symbol `path`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this[symbol] = 1;
+      }
+
+      if (Symbol) {
+        var symbol2 = Symbol('b');
+        Foo.prototype[symbol2] = 2;
+        var path = isHas ? symbol : symbol2;
+
+        assert.strictEqual(func(new Foo, path), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should work for objects with a `[[Prototype]]` of `null`', function(assert) {
+      assert.expect(1);
+
+      if (create)  {
+        var object = create(null);
+        object[1] = 'a';
+        assert.strictEqual(func(object, 1), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should check for a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': 1 };
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        assert.strictEqual(func(object, path), true);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for inherited properties', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.a = 1;
+
+      lodashStable.each(['a', ['a']], function(path) {
+        assert.strictEqual(func(new Foo, path), !isHas);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `' + (isHas ? 'false' : 'true') + '` for nested inherited properties', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.a = { 'b': 1 };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(func(new Foo, path), !isHas);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `true` for index values within bounds for arrays, `arguments` objects, and strings', function(assert) {
+      assert.expect(2);
+
+      var string = Object('abc');
+      delete args[0];
+      delete string[0];
+
+      var values = [Array(3), args, string],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(value, 0);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(values, lodashStable.constant([true, true]));
+
+      actual = lodashStable.map(values, function(value) {
+        return lodashStable.map(['a[0]', ['a', '0']], function(path) {
+          return func({ 'a': value }, path);
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+      args[0] = 1;
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `false` when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        var actual = lodashStable.map(values, function(value) {
+          return func(value, path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `false` for deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
+        var actual = lodashStable.map(values, function(value) {
+          return func(value, path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `false` for nullish values of nested objects', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var actual = lodashStable.map(values, function(value, index) {
+          var object = index ? { 'a': value } : {};
+          return func(object, path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.head');
+
+  (function() {
+    var array = [1, 2, 3, 4];
+
+    QUnit.test('should return the first element', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.head(array), 1);
+    });
+
+    QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
+      assert.expect(1);
+
+      arrayProto[0] = 1;
+      assert.strictEqual(_.head([]), undefined);
+      arrayProto.length = 0;
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.head);
+
+      assert.deepEqual(actual, [1, 4, 7]);
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_(array).head(), 1);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(array).chain().head() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _(array).chain().head();
+        assert.strictEqual(wrapped.__wrapped__, array);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
+            smallArray = array;
+
+        lodashStable.times(2, function(index) {
+          var array = index ? largeArray : smallArray,
+              wrapped = _(array).filter(isEven);
+
+          assert.strictEqual(wrapped.head(), _.head(_.filter(array, isEven)));
+        });
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.first, _.head);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.identity');
+
+  (function() {
+    QUnit.test('should return the first argument given', function(assert) {
+      assert.expect(1);
+
+      var object = { 'name': 'fred' };
+      assert.strictEqual(_.identity(object), object);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.includes');
+
+  (function() {
+    lodashStable.each({
+      'an `arguments` object': arguments,
+      'an array': [1, 2, 3, 4],
+      'an object': { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
+      'a string': '1234'
+    },
+    function(collection, key) {
+      var isStr = typeof collection == 'string',
+          values = _.toArray(collection),
+          length = values.length;
+
+      QUnit.test('should work with ' + key + ' and  return `true` for  matched values', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(_.includes(collection, 3), true);
+      });
+
+      QUnit.test('should work with ' + key + ' and  return `false` for unmatched values', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(_.includes(collection, 5), false);
+      });
+
+      QUnit.test('should work with ' + key + ' and a positive `fromIndex`', function(assert) {
+        assert.expect(2);
+
+        assert.strictEqual(_.includes(collection, values[2], 2), true);
+        assert.strictEqual(_.includes(collection, values[1], 2), false);
+      });
+
+      QUnit.test('should work with ' + key + ' and a `fromIndex` >= `collection.length`', function(assert) {
+        assert.expect(12);
+
+        lodashStable.each([4, 6, Math.pow(2, 32), Infinity], function(fromIndex) {
+          assert.strictEqual(_.includes(collection, 1, fromIndex), false);
+          assert.strictEqual(_.includes(collection, undefined, fromIndex), false);
+          assert.strictEqual(_.includes(collection, '', fromIndex), (isStr && fromIndex == length));
+        });
+      });
+
+      QUnit.test('should work with ' + key + ' and treat falsey `fromIndex` values as `0`', function(assert) {
+        assert.expect(1);
+
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(fromIndex) {
+          return _.includes(collection, values[0], fromIndex);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+
+      QUnit.test('should work with ' + key + ' and coerce non-integer `fromIndex` values to integers', function(assert) {
+        assert.expect(3);
+
+        assert.strictEqual(_.includes(collection, values[0], '1'), false);
+        assert.strictEqual(_.includes(collection, values[0], 0.1), true);
+        assert.strictEqual(_.includes(collection, values[0], NaN), true);
+      });
+
+      QUnit.test('should work with ' + key + ' and a negative `fromIndex`', function(assert) {
+        assert.expect(2);
+
+        assert.strictEqual(_.includes(collection, values[2], -2), true);
+        assert.strictEqual(_.includes(collection, values[1], -2), false);
+      });
+
+      QUnit.test('should work with ' + key + ' and a negative `fromIndex` <= negative `collection.length`', function(assert) {
+        assert.expect(3);
+
+        lodashStable.each([-4, -6, -Infinity], function(fromIndex) {
+          assert.strictEqual(_.includes(collection, values[0], fromIndex), true);
+        });
+      });
+
+      QUnit.test('should work with ' + key + ' and floor `position` values', function(assert) {
+        assert.expect(1);
+
+        assert.strictEqual(_.includes(collection, 2, 1.2), true);
+      });
+
+      QUnit.test('should work with ' + key + ' and return an unwrapped value implicitly when chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          assert.strictEqual(_(collection).includes(3), true);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('should work with ' + key + ' and return a wrapped value when explicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          assert.ok(_(collection).chain().includes(3) instanceof _);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    lodashStable.each({
+      'literal': 'abc',
+      'object': Object('abc')
+    },
+    function(collection, key) {
+      QUnit.test('should work with a string ' + key + ' for `collection`', function(assert) {
+        assert.expect(2);
+
+        assert.strictEqual(_.includes(collection, 'bc'), true);
+        assert.strictEqual(_.includes(collection, 'd'), false);
+      });
+    });
+
+    QUnit.test('should return `false` for empty collections', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, alwaysFalse);
+
+      var actual = lodashStable.map(empties, function(value) {
+        try {
+          return _.includes(value);
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should match `NaN`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.includes([1, NaN, 3], NaN), true);
+    });
+
+    QUnit.test('should match `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.includes([-0], 0), true);
+      assert.strictEqual(_.includes([0], -0), true);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.every`', function(assert) {
+      assert.expect(1);
+
+      var array1 = [1, 2, 3],
+          array2 = [2, 3, 1];
+
+      assert.ok(lodashStable.every(array1, lodashStable.partial(_.includes, array2)));
+    });
+  }(1, 2, 3, 4));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.indexOf');
+
+  (function() {
+    var array = [1, 2, 3, 1, 2, 3];
+
+    QUnit.test('should return the index of the first matched value', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.indexOf(array, 3), 2);
+    });
+
+    QUnit.test('should work with a positive `fromIndex`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.indexOf(array, 1, 2), 3);
+    });
+
+    QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
+      assert.expect(1);
+
+      var values = [6, 8, Math.pow(2, 32), Infinity],
+          expected = lodashStable.map(values, lodashStable.constant([-1, -1, -1]));
+
+      var actual = lodashStable.map(values, function(fromIndex) {
+        return [
+          _.indexOf(array, undefined, fromIndex),
+          _.indexOf(array, 1, fromIndex),
+          _.indexOf(array, '', fromIndex)
+        ];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with a negative `fromIndex`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.indexOf(array, 2, -3), 4);
+    });
+
+    QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
+      assert.expect(1);
+
+      var values = [-6, -8, -Infinity],
+          expected = lodashStable.map(values, alwaysZero);
+
+      var actual = lodashStable.map(values, function(fromIndex) {
+        return _.indexOf(array, 1, fromIndex);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat falsey `fromIndex` values as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysZero);
+
+      var actual = lodashStable.map(falsey, function(fromIndex) {
+        return _.indexOf(array, 1, fromIndex);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.indexOf(array, 2, 1.2), 1);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.initial');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should accept a falsey `array` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyArray);
+
+      var actual = lodashStable.map(falsey, function(array, index) {
+        try {
+          return index ? _.initial(array) : _.initial();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should exclude last element', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.initial(array), [1, 2]);
+    });
+
+    QUnit.test('should return an empty when querying empty arrays', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.initial([]), []);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.initial);
+
+      assert.deepEqual(actual, [[1, 2], [4, 5], [7, 8]]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            values = [];
+
+        var actual = _(array).initial().filter(function(value) {
+          values.push(value);
+          return false;
+        })
+        .value();
+
+        assert.deepEqual(actual, []);
+        assert.deepEqual(values, _.initial(array));
+
+        values = [];
+
+        actual = _(array).filter(function(value) {
+          values.push(value);
+          return isEven(value);
+        })
+        .initial()
+        .value();
+
+        assert.deepEqual(actual, _.initial(lodashStable.filter(array, isEven)));
+        assert.deepEqual(values, array);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.inRange');
+
+  (function() {
+    QUnit.test('should work with an `end` argument', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.inRange(3, 5), true);
+      assert.strictEqual(_.inRange(5, 5), false);
+      assert.strictEqual(_.inRange(6, 5), false);
+    });
+
+    QUnit.test('should work with `start` and `end` arguments', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.inRange(1, 1, 5), true);
+      assert.strictEqual(_.inRange(3, 1, 5), true);
+      assert.strictEqual(_.inRange(0, 1, 5), false);
+      assert.strictEqual(_.inRange(5, 1, 5), false);
+    });
+
+    QUnit.test('should treat falsey `start` arguments as `0`', function(assert) {
+      assert.expect(13);
+
+      lodashStable.each(falsey, function(value, index) {
+        if (index) {
+          assert.strictEqual(_.inRange(0, value), false);
+          assert.strictEqual(_.inRange(0, value, 1), true);
+        } else {
+          assert.strictEqual(_.inRange(0), false);
+        }
+      });
+    });
+
+    QUnit.test('should swap `start` and `end` when `start` > `end`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.inRange(2, 5, 1), true);
+      assert.strictEqual(_.inRange(-3, -2, -6), true);
+    });
+
+    QUnit.test('should work with a floating point `n` value', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.inRange(0.5, 5), true);
+      assert.strictEqual(_.inRange(1.2, 1, 5), true);
+      assert.strictEqual(_.inRange(5.2, 5), false);
+      assert.strictEqual(_.inRange(0.5, 1, 5), false);
+    });
+
+    QUnit.test('should coerce arguments to finite numbers', function(assert) {
+      assert.expect(1);
+
+      var actual = [_.inRange(0, '0', 1), _.inRange(0, '1'), _.inRange(0, 0, '1'), _.inRange(0, NaN, 1), _.inRange(-1, -1, NaN)],
+          expected = lodashStable.map(actual, alwaysTrue);
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('intersection methods');
+
+  lodashStable.each(['intersection', 'intersectionBy', 'intersectionWith'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return the intersection of two arrays', function(assert) {
+      assert.expect(2);
+
+      var actual = func([1, 3, 2], [5, 2, 1, 4]);
+      assert.deepEqual(actual, [1, 2]);
+
+      actual = func([5, 2, 1, 4], [1, 3, 2]);
+      assert.deepEqual(actual, [2, 1]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return the intersection of multiple arrays', function(assert) {
+      assert.expect(2);
+
+      var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
+      assert.deepEqual(actual, [1, 2]);
+
+      actual = func([5, 2, 1, 4], [2, 1], [1, 3, 2]);
+      assert.deepEqual(actual, [2, 1]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
+      assert.expect(1);
+
+      var actual = func([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1]);
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a single array', function(assert) {
+      assert.expect(1);
+
+      var actual = func([1, 1, 3, 2, 2]);
+      assert.deepEqual(actual, [1, 3, 2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
+      assert.expect(2);
+
+      var array = [0, 1, null, 3],
+          expected = [1, 3];
+
+      assert.deepEqual(func(array, args), expected);
+      assert.deepEqual(func(args, array), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
+      assert.expect(1);
+
+      var values = [-0, 0],
+          expected = lodashStable.map(values, lodashStable.constant(['0']));
+
+      var actual = lodashStable.map(values, function(value) {
+        return lodashStable.map(func(values, [value]), lodashStable.toString);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
+      assert.expect(1);
+
+      var actual = func([1, NaN, 3], [NaN, 5, NaN]);
+      assert.deepEqual(actual, [NaN]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
+      assert.expect(1);
+
+      var values = [-0, 0],
+          expected = lodashStable.map(values, lodashStable.constant(['0']));
+
+      var actual = lodashStable.map(values, function(value) {
+        var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(value));
+        return lodashStable.map(func(values, largeArray), lodashStable.toString);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of `NaN`', function(assert) {
+      assert.expect(1);
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysNaN);
+      assert.deepEqual(func([1, NaN, 3], largeArray), [NaN]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of objects', function(assert) {
+      assert.expect(2);
+
+      var object = {},
+          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, lodashStable.constant(object));
+
+      assert.deepEqual(func([object], largeArray), [object]);
+      assert.deepEqual(func(lodashStable.range(LARGE_ARRAY_SIZE), [1]), [1]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat values that are not arrays or `arguments` objects as empty', function(assert) {
+      assert.expect(3);
+
+      var array = [0, 1, null, 3];
+      assert.deepEqual(func(array, 3, { '0': 1 }, null), []);
+      assert.deepEqual(func(null, array, null, [2, 3]), []);
+      assert.deepEqual(func(array, null, args, null), []);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _([1, 3, 2])[methodName]([5, 2, 1, 4]);
+        assert.ok(wrapped instanceof _);
+        assert.deepEqual(wrapped.value(), [1, 2]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.intersectionBy');
+
+  (function() {
+    QUnit.test('should accept an `iteratee` argument', function(assert) {
+      assert.expect(2);
+
+      var actual = _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+      assert.deepEqual(actual, [2.1]);
+
+      actual = _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+      assert.deepEqual(actual, [{ 'x': 1 }]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.intersectionBy([2.1, 1.2], [4.3, 2.4], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [4.3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.intersectionWith');
+
+  (function() {
+    QUnit.test('should work with a `comparator` argument', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
+          others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
+          actual = _.intersectionWith(objects, others, lodashStable.isEqual);
+
+      assert.deepEqual(actual, [objects[0]]);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var array = [-0],
+          largeArray = lodashStable.times(LARGE_ARRAY_SIZE, alwaysZero),
+          others = [[0], largeArray],
+          expected = lodashStable.map(others, lodashStable.constant(['-0']));
+
+      var actual = lodashStable.map(others, function(other) {
+        return lodashStable.map(_.intersectionWith(array, other, lodashStable.eq), lodashStable.toString);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.invert');
+
+  (function() {
+    QUnit.test('should invert an object', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1, 'b': 2 },
+          actual = _.invert(object);
+
+      assert.deepEqual(actual, { '1': 'a', '2': 'b' });
+      assert.deepEqual(_.invert(actual), { 'a': '1', 'b': '2' });
+    });
+
+    QUnit.test('should work with values that shadow keys on `Object.prototype`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 'hasOwnProperty', 'b': 'constructor' };
+      assert.deepEqual(_.invert(object), { 'hasOwnProperty': 'a', 'constructor': 'b' });
+    });
+
+    QUnit.test('should work with an object that has a `length` property', function(assert) {
+      assert.expect(1);
+
+      var object = { '0': 'a', '1': 'b', 'length': 2 };
+      assert.deepEqual(_.invert(object), { 'a': '0', 'b': '1', '2': 'length' });
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var object = { 'a': 1, 'b': 2 },
+            wrapped = _(object).invert();
+
+        assert.ok(wrapped instanceof _);
+        assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' });
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.invertBy');
+
+  (function() {
+    var object = { 'a': 1, 'b': 2, 'c': 1 };
+
+    QUnit.test('should transform keys by `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'group1': ['a', 'c'], 'group2': ['b'] };
+
+      var actual = _.invertBy(object, function(value) {
+        return 'group' + value;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant({ '1': ['a', 'c'], '2': ['b'] }));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.invertBy(object, value) : _.invertBy(object);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should only add multiple values to own, not inherited, properties', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 'hasOwnProperty', 'b': 'constructor' },
+          expected = { 'hasOwnProperty': ['a'], 'constructor': ['b'] };
+
+      assert.ok(lodashStable.isEqual(_.invertBy(object), expected));
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _(object).invertBy();
+
+        assert.ok(wrapped instanceof _);
+        assert.deepEqual(wrapped.value(), { '1': ['a', 'c'], '2': ['b'] });
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.invoke');
+
+  (function() {
+    QUnit.test('should invoke a method on `object`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': lodashStable.constant('A') },
+          actual = _.invoke(object, 'a');
+
+      assert.strictEqual(actual, 'A');
+    });
+
+    QUnit.test('should support invoking with arguments', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': function(a, b) { return [a, b]; } },
+          actual = _.invoke(object, 'a', 1, 2);
+
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('should not error on nullish elements', function(assert) {
+      assert.expect(1);
+
+      var values = [null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      var actual = lodashStable.map(values, function(value) {
+        try {
+          return _.invoke(value, 'a.b', 1, 2);
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': alwaysA, '0': alwaysB },
+          props = [-0, Object(-0), 0, Object(0)];
+
+      var actual = lodashStable.map(props, function(key) {
+        return _.invoke(object, key);
+      });
+
+      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
+    });
+
+    QUnit.test('should support deep paths', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': function(a, b) { return [a, b]; } } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var actual = _.invoke(object, path, 1, 2);
+        assert.deepEqual(actual, [1, 2]);
+      });
+    });
+
+    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.deepEqual(_.invoke(object, path), 1);
+      });
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var object = { 'a': alwaysOne };
+        assert.strictEqual(_(object).invoke('a'), 1);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var object = { 'a': alwaysOne };
+        assert.ok(_(object).chain().invoke('a') instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.invokeMap');
+
+  (function() {
+    QUnit.test('should invoke a methods on each element of `collection`', function(assert) {
+      assert.expect(1);
+
+      var array = ['a', 'b', 'c'],
+          actual = _.invokeMap(array, 'toUpperCase');
+
+      assert.deepEqual(actual, ['A', 'B', 'C']);
+    });
+
+    QUnit.test('should support invoking with arguments', function(assert) {
+      assert.expect(1);
+
+      var array = [function() { return slice.call(arguments); }],
+          actual = _.invokeMap(array, 'call', null, 'a', 'b', 'c');
+
+      assert.deepEqual(actual, [['a', 'b', 'c']]);
+    });
+
+    QUnit.test('should work with a function for `methodName`', function(assert) {
+      assert.expect(1);
+
+      var array = ['a', 'b', 'c'];
+
+      var actual = _.invokeMap(array, function(left, right) {
+        return left + this.toUpperCase() + right;
+      }, '(', ')');
+
+      assert.deepEqual(actual, ['(A)', '(B)', '(C)']);
+    });
+
+    QUnit.test('should work with an object for `collection`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          actual = _.invokeMap(object, 'toFixed', 1);
+
+      assert.deepEqual(actual, ['1.0', '2.0', '3.0']);
+    });
+
+    QUnit.test('should treat number values for `collection` as empty', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.invokeMap(1), []);
+    });
+
+    QUnit.test('should not error on nullish elements', function(assert) {
+      assert.expect(1);
+
+      var array = ['a', null, undefined, 'd'];
+
+      try {
+        var actual = _.invokeMap(array, 'toUpperCase');
+      } catch (e) {}
+
+      assert.deepEqual(actual, ['A', undefined, undefined, 'D']);
+    });
+
+    QUnit.test('should not error on elements with missing properties', function(assert) {
+      assert.expect(1);
+
+      var objects = lodashStable.map([null, undefined, alwaysOne], function(value) {
+        return { 'a': value };
+      });
+
+      var expected = lodashStable.map(objects, function(object) {
+        return object.a ? object.a() : undefined;
+      });
+
+      try {
+        var actual = _.invokeMap(objects, 'a');
+      } catch (e) {}
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.deepEqual(_.invokeMap([object], path), [1]);
+      });
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var array = ['a', 'b', 'c'],
+            wrapped = _(array),
+            actual = wrapped.invokeMap('toUpperCase');
+
+        assert.ok(actual instanceof _);
+        assert.deepEqual(actual.valueOf(), ['A', 'B', 'C']);
+
+        actual = wrapped.invokeMap(function(left, right) {
+          return left + this.toUpperCase() + right;
+        }, '(', ')');
+
+        assert.ok(actual instanceof _);
+        assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should support shortcut fusion', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var count = 0,
+            method = function() { count++; return this.index; };
+
+        var array = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
+          return { 'index': index, 'method': method };
+        });
+
+        var actual = _(array).invokeMap('method').take(1).value();
+
+        assert.strictEqual(count, 1);
+        assert.deepEqual(actual, [0]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isArguments');
+
+  (function() {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3));
+
+    QUnit.test('should return `true` for `arguments` objects', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isArguments(args), true);
+      assert.strictEqual(_.isArguments(strictArgs), true);
+    });
+
+    QUnit.test('should return `false` for non `arguments` objects', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isArguments(value) : _.isArguments();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isArguments([1, 2, 3]), false);
+      assert.strictEqual(_.isArguments(true), false);
+      assert.strictEqual(_.isArguments(new Date), false);
+      assert.strictEqual(_.isArguments(new Error), false);
+      assert.strictEqual(_.isArguments(_), false);
+      assert.strictEqual(_.isArguments(slice), false);
+      assert.strictEqual(_.isArguments({ '0': 1, 'callee': noop, 'length': 1 }), false);
+      assert.strictEqual(_.isArguments(1), false);
+      assert.strictEqual(_.isArguments(/x/), false);
+      assert.strictEqual(_.isArguments('a'), false);
+      assert.strictEqual(_.isArguments(symbol), false);
+    });
+
+    QUnit.test('should work with an `arguments` object from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.arguments) {
+        assert.strictEqual(_.isArguments(realm.arguments), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isArray');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for arrays', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isArray([1, 2, 3]), true);
+    });
+
+    QUnit.test('should return `false` for non-arrays', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isArray(value) : _.isArray();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isArray(args), false);
+      assert.strictEqual(_.isArray(true), false);
+      assert.strictEqual(_.isArray(new Date), false);
+      assert.strictEqual(_.isArray(new Error), false);
+      assert.strictEqual(_.isArray(_), false);
+      assert.strictEqual(_.isArray(slice), false);
+      assert.strictEqual(_.isArray({ '0': 1, 'length': 1 }), false);
+      assert.strictEqual(_.isArray(1), false);
+      assert.strictEqual(_.isArray(/x/), false);
+      assert.strictEqual(_.isArray('a'), false);
+      assert.strictEqual(_.isArray(symbol), false);
+    });
+
+    QUnit.test('should work with an array from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.array) {
+        assert.strictEqual(_.isArray(realm.array), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isArrayBuffer');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for array buffers', function(assert) {
+      assert.expect(1);
+
+      if (ArrayBuffer) {
+        assert.strictEqual(_.isArrayBuffer(arrayBuffer), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non array buffers', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isArrayBuffer(value) : _.isArrayBuffer();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isArrayBuffer(args), false);
+      assert.strictEqual(_.isArrayBuffer([1, 2, 3]), false);
+      assert.strictEqual(_.isArrayBuffer(true), false);
+      assert.strictEqual(_.isArrayBuffer(new Date), false);
+      assert.strictEqual(_.isArrayBuffer(new Error), false);
+      assert.strictEqual(_.isArrayBuffer(_), false);
+      assert.strictEqual(_.isArrayBuffer(slice), false);
+      assert.strictEqual(_.isArrayBuffer({ 'a': 1 }), false);
+      assert.strictEqual(_.isArrayBuffer(1), false);
+      assert.strictEqual(_.isArrayBuffer(/x/), false);
+      assert.strictEqual(_.isArrayBuffer('a'), false);
+      assert.strictEqual(_.isArrayBuffer(symbol), false);
+    });
+
+    QUnit.test('should work with array buffers from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.arrayBuffer) {
+        assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isArrayLike');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for array-like values', function(assert) {
+      assert.expect(1);
+
+      var values = [args, [1, 2, 3], { '0': 1, 'length': 1 }, 'a'],
+          expected = lodashStable.map(values, alwaysTrue),
+          actual = lodashStable.map(values, _.isArrayLike);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-arrays', function(assert) {
+      assert.expect(11);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === '';
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isArrayLike(value) : _.isArrayLike();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isArrayLike(true), false);
+      assert.strictEqual(_.isArrayLike(new Date), false);
+      assert.strictEqual(_.isArrayLike(new Error), false);
+      assert.strictEqual(_.isArrayLike(_), false);
+      assert.strictEqual(_.isArrayLike(generator), false);
+      assert.strictEqual(_.isArrayLike(slice), false);
+      assert.strictEqual(_.isArrayLike({ 'a': 1 }), false);
+      assert.strictEqual(_.isArrayLike(1), false);
+      assert.strictEqual(_.isArrayLike(/x/), false);
+      assert.strictEqual(_.isArrayLike(symbol), false);
+    });
+
+    QUnit.test('should work with an array from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.object) {
+        var values = [realm.arguments, realm.array, realm.string],
+            expected = lodashStable.map(values, alwaysTrue),
+            actual = lodashStable.map(values, _.isArrayLike);
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isBoolean');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for booleans', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.isBoolean(true), true);
+      assert.strictEqual(_.isBoolean(false), true);
+      assert.strictEqual(_.isBoolean(Object(true)), true);
+      assert.strictEqual(_.isBoolean(Object(false)), true);
+    });
+
+    QUnit.test('should return `false` for non-booleans', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === false;
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isBoolean(value) : _.isBoolean();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isBoolean(args), false);
+      assert.strictEqual(_.isBoolean([1, 2, 3]), false);
+      assert.strictEqual(_.isBoolean(new Date), false);
+      assert.strictEqual(_.isBoolean(new Error), false);
+      assert.strictEqual(_.isBoolean(_), false);
+      assert.strictEqual(_.isBoolean(slice), false);
+      assert.strictEqual(_.isBoolean({ 'a': 1 }), false);
+      assert.strictEqual(_.isBoolean(1), false);
+      assert.strictEqual(_.isBoolean(/x/), false);
+      assert.strictEqual(_.isBoolean('a'), false);
+      assert.strictEqual(_.isBoolean(symbol), false);
+    });
+
+    QUnit.test('should work with a boolean from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.boolean) {
+        assert.strictEqual(_.isBoolean(realm.boolean), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isBuffer');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for buffers', function(assert) {
+      assert.expect(1);
+
+      if (Buffer) {
+        assert.strictEqual(_.isBuffer(new Buffer(2)), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non-buffers', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isBuffer(value) : _.isBuffer();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isBuffer(args), false);
+      assert.strictEqual(_.isBuffer([1, 2, 3]), false);
+      assert.strictEqual(_.isBuffer(true), false);
+      assert.strictEqual(_.isBuffer(new Date), false);
+      assert.strictEqual(_.isBuffer(new Error), false);
+      assert.strictEqual(_.isBuffer(_), false);
+      assert.strictEqual(_.isBuffer(slice), false);
+      assert.strictEqual(_.isBuffer({ 'a': 1 }), false);
+      assert.strictEqual(_.isBuffer(1), false);
+      assert.strictEqual(_.isBuffer(/x/), false);
+      assert.strictEqual(_.isBuffer('a'), false);
+      assert.strictEqual(_.isBuffer(symbol), false);
+    });
+
+    QUnit.test('should return `false` if `Buffer` is not defined', function(assert) {
+      assert.expect(1);
+
+      if (!isStrict && Buffer && lodashBizarro) {
+        assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isDate');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for dates', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isDate(new Date), true);
+    });
+
+    QUnit.test('should return `false` for non-dates', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isDate(value) : _.isDate();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isDate(args), false);
+      assert.strictEqual(_.isDate([1, 2, 3]), false);
+      assert.strictEqual(_.isDate(true), false);
+      assert.strictEqual(_.isDate(new Error), false);
+      assert.strictEqual(_.isDate(_), false);
+      assert.strictEqual(_.isDate(slice), false);
+      assert.strictEqual(_.isDate({ 'a': 1 }), false);
+      assert.strictEqual(_.isDate(1), false);
+      assert.strictEqual(_.isDate(/x/), false);
+      assert.strictEqual(_.isDate('a'), false);
+      assert.strictEqual(_.isDate(symbol), false);
+    });
+
+    QUnit.test('should work with a date object from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.date) {
+        assert.strictEqual(_.isDate(realm.date), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isElement');
+
+  (function() {
+    var args = arguments;
+
+    function Element() {
+      this.nodeType = 1;
+    }
+
+    QUnit.test('should return `false` for plain objects', function(assert) {
+      assert.expect(7);
+
+      var element = body || new Element;
+
+      assert.strictEqual(_.isElement(element), true);
+      assert.strictEqual(_.isElement({ 'nodeType': 1 }), false);
+      assert.strictEqual(_.isElement({ 'nodeType': Object(1) }), false);
+      assert.strictEqual(_.isElement({ 'nodeType': true }), false);
+      assert.strictEqual(_.isElement({ 'nodeType': [1] }), false);
+      assert.strictEqual(_.isElement({ 'nodeType': '1' }), false);
+      assert.strictEqual(_.isElement({ 'nodeType': '001' }), false);
+    });
+
+    QUnit.test('should return `false` for non DOM elements', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isElement(value) : _.isElement();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isElement(args), false);
+      assert.strictEqual(_.isElement([1, 2, 3]), false);
+      assert.strictEqual(_.isElement(true), false);
+      assert.strictEqual(_.isElement(new Date), false);
+      assert.strictEqual(_.isElement(new Error), false);
+      assert.strictEqual(_.isElement(_), false);
+      assert.strictEqual(_.isElement(slice), false);
+      assert.strictEqual(_.isElement({ 'a': 1 }), false);
+      assert.strictEqual(_.isElement(1), false);
+      assert.strictEqual(_.isElement(/x/), false);
+      assert.strictEqual(_.isElement('a'), false);
+      assert.strictEqual(_.isElement(symbol), false);
+    });
+
+    QUnit.test('should work with a DOM element from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.element) {
+        assert.strictEqual(_.isElement(realm.element), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isEmpty');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for empty values', function(assert) {
+      assert.expect(10);
+
+      var expected = lodashStable.map(empties, alwaysTrue),
+          actual = lodashStable.map(empties, _.isEmpty);
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isEmpty(true), true);
+      assert.strictEqual(_.isEmpty(slice), true);
+      assert.strictEqual(_.isEmpty(1), true);
+      assert.strictEqual(_.isEmpty(NaN), true);
+      assert.strictEqual(_.isEmpty(/x/), true);
+      assert.strictEqual(_.isEmpty(symbol), true);
+      assert.strictEqual(_.isEmpty(), true);
+
+      if (Buffer) {
+        assert.strictEqual(_.isEmpty(new Buffer(0)), true);
+        assert.strictEqual(_.isEmpty(new Buffer(1)), false);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should return `false` for non-empty values', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.isEmpty([0]), false);
+      assert.strictEqual(_.isEmpty({ 'a': 0 }), false);
+      assert.strictEqual(_.isEmpty('a'), false);
+    });
+
+    QUnit.test('should work with an object that has a `length` property', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isEmpty({ 'length': 0 }), false);
+    });
+
+    QUnit.test('should work with `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isEmpty(args), false);
+    });
+
+    QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
+      assert.expect(1);
+
+      function Foo(elements) {
+        push.apply(this, elements);
+      }
+      Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
+
+      assert.strictEqual(_.isEmpty(new Foo([])), true);
+    });
+
+    QUnit.test('should work with maps', function(assert) {
+      assert.expect(4);
+
+      if (Map) {
+        lodashStable.each([new Map, realm.map], function(map) {
+          assert.strictEqual(_.isEmpty(map), true);
+          map.set('a', 1);
+          assert.strictEqual(_.isEmpty(map), false);
+          map.clear();
+        });
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should work with sets', function(assert) {
+      assert.expect(4);
+
+      if (Set) {
+        lodashStable.each([new Set, realm.set], function(set) {
+          assert.strictEqual(_.isEmpty(set), true);
+          set.add(1);
+          assert.strictEqual(_.isEmpty(set), false);
+          set.clear();
+        });
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype.length = -1;
+
+      assert.strictEqual(_.isEmpty(new Foo), true);
+    });
+
+    QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype.length = MAX_SAFE_INTEGER + 1;
+
+      assert.strictEqual(_.isEmpty(new Foo), true);
+    });
+
+    QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isEmpty({ 'length': '0' }), false);
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_({}).isEmpty(), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_({}).chain().isEmpty() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isEqual');
+
+  (function() {
+    var symbol1 = Symbol ? Symbol('a') : true,
+        symbol2 = Symbol ? Symbol('b') : false;
+
+    QUnit.test('should compare primitives', function(assert) {
+      assert.expect(1);
+
+      var pairs = [
+        [1, 1, true], [1, Object(1), true], [1, '1', false], [1, 2, false],
+        [-0, -0, true], [0, 0, true], [0, Object(0), true], [Object(0), Object(0), true], [-0, 0, true], [0, '0', false], [0, null, false],
+        [NaN, NaN, true], [NaN, Object(NaN), true], [Object(NaN), Object(NaN), true], [NaN, 'a', false], [NaN, Infinity, false],
+        ['a', 'a', true], ['a', Object('a'), true], [Object('a'), Object('a'), true], ['a', 'b', false], ['a', ['a'], false],
+        [true, true, true], [true, Object(true), true], [Object(true), Object(true), true], [true, 1, false], [true, 'a', false],
+        [false, false, true], [false, Object(false), true], [Object(false), Object(false), true], [false, 0, false], [false, '', false],
+        [symbol1, symbol1, true], [symbol1, Object(symbol1), true], [Object(symbol1), Object(symbol1), true], [symbol1, symbol2, false],
+        [null, null, true], [null, undefined, false], [null, {}, false], [null, '', false],
+        [undefined, undefined, true], [undefined, null, false], [undefined, '', false]
+      ];
+
+      var expected = lodashStable.map(pairs, function(pair) {
+        return pair[2];
+      });
+
+      var actual = lodashStable.map(pairs, function(pair) {
+        return _.isEqual(pair[0], pair[1]);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should compare arrays', function(assert) {
+      assert.expect(6);
+
+      var array1 = [true, null, 1, 'a', undefined],
+          array2 = [true, null, 1, 'a', undefined];
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
+      array2 = [[1, 2, 3], new Date(2012, 4, 23), /x/, { 'e': 1 }];
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1 = [1];
+      array1[2] = 3;
+
+      array2 = [1];
+      array2[1] = undefined;
+      array2[2] = 3;
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1 = [Object(1), false, Object('a'), /x/, new Date(2012, 4, 23), ['a', 'b', [Object('c')]], { 'a': 1 }];
+      array2 = [1, Object(false), 'a', /x/, new Date(2012, 4, 23), ['a', Object('b'), ['c']], { 'a': 1 }];
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1 = [1, 2, 3];
+      array2 = [3, 2, 1];
+
+      assert.strictEqual(_.isEqual(array1, array2), false);
+
+      array1 = [1, 2];
+      array2 = [1, 2, 3];
+
+      assert.strictEqual(_.isEqual(array1, array2), false);
+    });
+
+    QUnit.test('should treat arrays with identical values but different non-index properties as equal', function(assert) {
+      assert.expect(3);
+
+      var array1 = [1, 2, 3],
+          array2 = [1, 2, 3];
+
+      array1.every = array1.filter = array1.forEach =
+      array1.indexOf = array1.lastIndexOf = array1.map =
+      array1.some = array1.reduce = array1.reduceRight = null;
+
+      array2.concat = array2.join = array2.pop =
+      array2.reverse = array2.shift = array2.slice =
+      array2.sort = array2.splice = array2.unshift = null;
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1 = [1, 2, 3];
+      array1.a = 1;
+
+      array2 = [1, 2, 3];
+      array2.b = 1;
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1 = /c/.exec('abcde');
+      array2 = ['c'];
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+    });
+
+    QUnit.test('should compare sparse arrays', function(assert) {
+      assert.expect(3);
+
+      var array = Array(1);
+
+      assert.strictEqual(_.isEqual(array, Array(1)), true);
+      assert.strictEqual(_.isEqual(array, [undefined]), true);
+      assert.strictEqual(_.isEqual(array, Array(2)), false);
+    });
+
+    QUnit.test('should compare plain objects', function(assert) {
+      assert.expect(5);
+
+      var object1 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined },
+          object2 = { 'a': true, 'b': null, 'c': 1, 'd': 'a', 'e': undefined };
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+
+      object1 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
+      object2 = { 'a': [1, 2, 3], 'b': new Date(2012, 4, 23), 'c': /x/, 'd': { 'e': 1 } };
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+
+      object1 = { 'a': 1, 'b': 2, 'c': 3 };
+      object2 = { 'a': 3, 'b': 2, 'c': 1 };
+
+      assert.strictEqual(_.isEqual(object1, object2), false);
+
+      object1 = { 'a': 1, 'b': 2, 'c': 3 };
+      object2 = { 'd': 1, 'e': 2, 'f': 3 };
+
+      assert.strictEqual(_.isEqual(object1, object2), false);
+
+      object1 = { 'a': 1, 'b': 2 };
+      object2 = { 'a': 1, 'b': 2, 'c': 3 };
+
+      assert.strictEqual(_.isEqual(object1, object2), false);
+    });
+
+    QUnit.test('should compare objects regardless of key order', function(assert) {
+      assert.expect(1);
+
+      var object1 = { 'a': 1, 'b': 2, 'c': 3 },
+          object2 = { 'c': 3, 'a': 1, 'b': 2 };
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+    });
+
+    QUnit.test('should compare nested objects', function(assert) {
+      assert.expect(1);
+
+      var object1 = {
+        'a': [1, 2, 3],
+        'b': true,
+        'c': Object(1),
+        'd': 'a',
+        'e': {
+          'f': ['a', Object('b'), 'c'],
+          'g': Object(false),
+          'h': new Date(2012, 4, 23),
+          'i': noop,
+          'j': 'a'
+        }
+      };
+
+      var object2 = {
+        'a': [1, Object(2), 3],
+        'b': Object(true),
+        'c': 1,
+        'd': Object('a'),
+        'e': {
+          'f': ['a', 'b', 'c'],
+          'g': false,
+          'h': new Date(2012, 4, 23),
+          'i': noop,
+          'j': 'a'
+        }
+      };
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+    });
+
+    QUnit.test('should compare object instances', function(assert) {
+      assert.expect(4);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.a = 1;
+
+      function Bar() {
+        this.a = 1;
+      }
+      Bar.prototype.a = 2;
+
+      assert.strictEqual(_.isEqual(new Foo, new Foo), true);
+      assert.strictEqual(_.isEqual(new Foo, new Bar), false);
+      assert.strictEqual(_.isEqual({ 'a': 1 }, new Foo), false);
+      assert.strictEqual(_.isEqual({ 'a': 2 }, new Bar), false);
+    });
+
+    QUnit.test('should compare objects with constructor properties', function(assert) {
+      assert.expect(5);
+
+      assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': 1 }), true);
+      assert.strictEqual(_.isEqual({ 'constructor': 1 },   { 'constructor': '1' }), false);
+      assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': [1] }), true);
+      assert.strictEqual(_.isEqual({ 'constructor': [1] }, { 'constructor': ['1'] }), false);
+      assert.strictEqual(_.isEqual({ 'constructor': Object }, {}), false);
+    });
+
+    QUnit.test('should compare arrays with circular references', function(assert) {
+      assert.expect(4);
+
+      var array1 = [],
+          array2 = [];
+
+      array1.push(array1);
+      array2.push(array2);
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1.push('b');
+      array2.push('b');
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1.push('c');
+      array2.push('d');
+
+      assert.strictEqual(_.isEqual(array1, array2), false);
+
+      array1 = ['a', 'b', 'c'];
+      array1[1] = array1;
+      array2 = ['a', ['a', 'b', 'c'], 'c'];
+
+      assert.strictEqual(_.isEqual(array1, array2), false);
+    });
+
+    QUnit.test('should compare objects with circular references', function(assert) {
+      assert.expect(4);
+
+      var object1 = {},
+          object2 = {};
+
+      object1.a = object1;
+      object2.a = object2;
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+
+      object1.b = 0;
+      object2.b = Object(0);
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+
+      object1.c = Object(1);
+      object2.c = Object(2);
+
+      assert.strictEqual(_.isEqual(object1, object2), false);
+
+      object1 = { 'a': 1, 'b': 2, 'c': 3 };
+      object1.b = object1;
+      object2 = { 'a': 1, 'b': { 'a': 1, 'b': 2, 'c': 3 }, 'c': 3 };
+
+      assert.strictEqual(_.isEqual(object1, object2), false);
+    });
+
+    QUnit.test('should compare objects with multiple circular references', function(assert) {
+      assert.expect(3);
+
+      var array1 = [{}],
+          array2 = [{}];
+
+      (array1[0].a = array1).push(array1);
+      (array2[0].a = array2).push(array2);
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1[0].b = 0;
+      array2[0].b = Object(0);
+
+      assert.strictEqual(_.isEqual(array1, array2), true);
+
+      array1[0].c = Object(1);
+      array2[0].c = Object(2);
+
+      assert.strictEqual(_.isEqual(array1, array2), false);
+    });
+
+    QUnit.test('should compare objects with complex circular references', function(assert) {
+      assert.expect(1);
+
+      var object1 = {
+        'foo': { 'b': { 'c': { 'd': {} } } },
+        'bar': { 'a': 2 }
+      };
+
+      var object2 = {
+        'foo': { 'b': { 'c': { 'd': {} } } },
+        'bar': { 'a': 2 }
+      };
+
+      object1.foo.b.c.d = object1;
+      object1.bar.b = object1.foo.b;
+
+      object2.foo.b.c.d = object2;
+      object2.bar.b = object2.foo.b;
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+    });
+
+    QUnit.test('should compare objects with shared property values', function(assert) {
+      assert.expect(1);
+
+      var object1 = {
+        'a': [1, 2]
+      };
+
+      var object2 = {
+        'a': [1, 2],
+        'b': [1, 2]
+      };
+
+      object1.b = object1.a;
+
+      assert.strictEqual(_.isEqual(object1, object2), true);
+    });
+
+    QUnit.test('should treat objects created by `Object.create(null)` like a plain object', function(assert) {
+      assert.expect(2);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.constructor = null;
+
+      var object2 = { 'a': 1 };
+      assert.strictEqual(_.isEqual(new Foo, object2), false);
+
+      if (create)  {
+        var object1 = create(null);
+        object1.a = 1;
+        assert.strictEqual(_.isEqual(object1, object2), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for objects with custom `toString` methods', function(assert) {
+      assert.expect(1);
+
+      var primitive,
+          object = { 'toString': function() { return primitive; } },
+          values = [true, null, 1, 'a', undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value) {
+        primitive = value;
+        return _.isEqual(object, value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should avoid common type coercions', function(assert) {
+      assert.expect(9);
+
+      assert.strictEqual(_.isEqual(true, Object(false)), false);
+      assert.strictEqual(_.isEqual(Object(false), Object(0)), false);
+      assert.strictEqual(_.isEqual(false, Object('')), false);
+      assert.strictEqual(_.isEqual(Object(36), Object('36')), false);
+      assert.strictEqual(_.isEqual(0, ''), false);
+      assert.strictEqual(_.isEqual(1, true), false);
+      assert.strictEqual(_.isEqual(1337756400000, new Date(2012, 4, 23)), false);
+      assert.strictEqual(_.isEqual('36', 36), false);
+      assert.strictEqual(_.isEqual(36, '36'), false);
+    });
+
+    QUnit.test('should compare `arguments` objects', function(assert) {
+      assert.expect(2);
+
+      var args1 = (function() { return arguments; }(1, 2, 3)),
+          args2 = (function() { return arguments; }(1, 2, 3)),
+          args3 = (function() { return arguments; }(1, 2));
+
+      assert.strictEqual(_.isEqual(args1, args2), true);
+      assert.strictEqual(_.isEqual(args1, args3), false);
+    });
+
+    QUnit.test('should treat `arguments` objects like `Object` objects', function(assert) {
+      assert.expect(4);
+
+      var args = (function() { return arguments; }(1, 2, 3)),
+          object = { '0': 1, '1': 2, '2': 3 };
+
+      function Foo() {}
+      Foo.prototype = object;
+
+      assert.strictEqual(_.isEqual(args, object), true);
+      assert.strictEqual(_.isEqual(object, args), true);
+
+      assert.strictEqual(_.isEqual(args, new Foo), false);
+      assert.strictEqual(_.isEqual(new Foo, args), false);
+    });
+
+    QUnit.test('should compare array buffers', function(assert) {
+      assert.expect(2);
+
+      if (ArrayBuffer) {
+        var buffer1 = new ArrayBuffer(4),
+            buffer2 = new ArrayBuffer(8);
+
+        assert.strictEqual(_.isEqual(buffer1, buffer2), false);
+
+        buffer1 = new Int8Array([-1]).buffer;
+        buffer2 = new Uint8Array([255]).buffer;
+
+        assert.strictEqual(_.isEqual(buffer1, buffer2), true);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should compare array views', function(assert) {
+      assert.expect(2);
+
+      lodashStable.times(2, function(index) {
+        var ns = index ? realm : root;
+
+        var pairs = lodashStable.map(arrayViews, function(type, viewIndex) {
+          var otherType = arrayViews[(viewIndex + 1) % arrayViews.length],
+              CtorA = ns[type] || function(n) { this.n = n; },
+              CtorB = ns[otherType] || function(n) { this.n = n; },
+              bufferA = ns[type] ? new ns.ArrayBuffer(8) : 8,
+              bufferB = ns[otherType] ? new ns.ArrayBuffer(8) : 8,
+              bufferC = ns[otherType] ? new ns.ArrayBuffer(16) : 16;
+
+          return [new CtorA(bufferA), new CtorA(bufferA), new CtorB(bufferB), new CtorB(bufferC)];
+        });
+
+        var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
+
+        var actual = lodashStable.map(pairs, function(pair) {
+          return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should compare date objects', function(assert) {
+      assert.expect(4);
+
+      var date = new Date(2012, 4, 23);
+
+      assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true);
+      assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false);
+      assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false);
+      assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false);
+    });
+
+    QUnit.test('should compare error objects', function(assert) {
+      assert.expect(1);
+
+      var pairs = lodashStable.map([
+        'Error',
+        'EvalError',
+        'RangeError',
+        'ReferenceError',
+        'SyntaxError',
+        'TypeError',
+        'URIError'
+      ], function(type, index, errorTypes) {
+        var otherType = errorTypes[++index % errorTypes.length],
+            CtorA = root[type],
+            CtorB = root[otherType];
+
+        return [new CtorA('a'), new CtorA('a'), new CtorB('a'), new CtorB('b')];
+      });
+
+      var expected = lodashStable.map(pairs, lodashStable.constant([true, false, false]));
+
+      var actual = lodashStable.map(pairs, function(pair) {
+        return [_.isEqual(pair[0], pair[1]), _.isEqual(pair[0], pair[2]), _.isEqual(pair[2], pair[3])];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should compare functions', function(assert) {
+      assert.expect(2);
+
+      function a() { return 1 + 2; }
+      function b() { return 1 + 2; }
+
+      assert.strictEqual(_.isEqual(a, a), true);
+      assert.strictEqual(_.isEqual(a, b), false);
+    });
+
+    QUnit.test('should compare maps', function(assert) {
+      assert.expect(8);
+
+      if (Map) {
+        lodashStable.each([[map, new Map], [map, realm.map]], function(maps) {
+          var map1 = maps[0],
+              map2 = maps[1];
+
+          map1.set('a', 1);
+          map2.set('b', 2);
+          assert.strictEqual(_.isEqual(map1, map2), false);
+
+          map1.set('b', 2);
+          map2.set('a', 1);
+          assert.strictEqual(_.isEqual(map1, map2), true);
+
+          map1['delete']('a');
+          map1.set('a', 1);
+          assert.strictEqual(_.isEqual(map1, map2), true);
+
+          map2['delete']('a');
+          assert.strictEqual(_.isEqual(map1, map2), false);
+
+          map1.clear();
+          map2.clear();
+        });
+      }
+      else {
+        skipAssert(assert, 8);
+      }
+    });
+
+    QUnit.test('should compare maps with circular references', function(assert) {
+      assert.expect(2);
+
+      if (Map) {
+        var map1 = new Map,
+            map2 = new Map;
+
+        map1.set('a', map1);
+        map2.set('a', map2);
+        assert.strictEqual(_.isEqual(map1, map2), true);
+
+        map1.set('b', 1);
+        map2.set('b', 2);
+        assert.strictEqual(_.isEqual(map1, map2), false);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should compare promises by reference', function(assert) {
+      assert.expect(4);
+
+      if (promise) {
+        lodashStable.each([[promise, Promise.resolve(1)], [promise, realm.promise]], function(promises) {
+          var promise1 = promises[0],
+              promise2 = promises[1];
+
+          assert.strictEqual(_.isEqual(promise1, promise2), false);
+          assert.strictEqual(_.isEqual(promise1, promise1), true);
+        });
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should compare regexes', function(assert) {
+      assert.expect(5);
+
+      assert.strictEqual(_.isEqual(/x/gim, /x/gim), true);
+      assert.strictEqual(_.isEqual(/x/gim, /x/mgi), true);
+      assert.strictEqual(_.isEqual(/x/gi, /x/g), false);
+      assert.strictEqual(_.isEqual(/x/, /y/), false);
+      assert.strictEqual(_.isEqual(/x/g, { 'global': true, 'ignoreCase': false, 'multiline': false, 'source': 'x' }), false);
+    });
+
+    QUnit.test('should compare sets', function(assert) {
+      assert.expect(8);
+
+      if (Set) {
+        lodashStable.each([[set, new Set], [set, realm.set]], function(sets) {
+          var set1 = sets[0],
+              set2 = sets[1];
+
+          set1.add(1);
+          set2.add(2);
+          assert.strictEqual(_.isEqual(set1, set2), false);
+
+          set1.add(2);
+          set2.add(1);
+          assert.strictEqual(_.isEqual(set1, set2), true);
+
+          set1['delete'](1);
+          set1.add(1);
+          assert.strictEqual(_.isEqual(set1, set2), true);
+
+          set2['delete'](1);
+          assert.strictEqual(_.isEqual(set1, set2), false);
+
+          set1.clear();
+          set2.clear();
+        });
+      }
+      else {
+        skipAssert(assert, 8);
+      }
+    });
+
+    QUnit.test('should compare sets with circular references', function(assert) {
+      assert.expect(2);
+
+      if (Set) {
+        var set1 = new Set,
+            set2 = new Set;
+
+        set1.add(set1);
+        set2.add(set2);
+        assert.strictEqual(_.isEqual(set1, set2), true);
+
+        set1.add(1);
+        set2.add(2);
+        assert.strictEqual(_.isEqual(set1, set2), false);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should work as an iteratee for `_.every`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.every([1, 1, 1], lodashStable.partial(_.isEqual, 1));
+      assert.ok(actual);
+    });
+
+    QUnit.test('should return `true` for like-objects from different documents', function(assert) {
+      assert.expect(4);
+
+      if (realm.object) {
+        assert.strictEqual(_.isEqual([1], realm.array), true);
+        assert.strictEqual(_.isEqual([2], realm.array), false);
+        assert.strictEqual(_.isEqual({ 'a': 1 }, realm.object), true);
+        assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should not error on DOM elements', function(assert) {
+      assert.expect(1);
+
+      if (document) {
+        var element1 = document.createElement('div'),
+            element2 = element1.cloneNode(true);
+
+        try {
+          assert.strictEqual(_.isEqual(element1, element2), false);
+        } catch (e) {
+          assert.ok(false, e.message);
+        }
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should compare wrapped values', function(assert) {
+      assert.expect(32);
+
+      var stamp = +new Date;
+
+      var values = [
+        [[1, 2], [1, 2], [1, 2, 3]],
+        [true, true, false],
+        [new Date(stamp), new Date(stamp), new Date(stamp - 100)],
+        [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 1 }],
+        [1, 1, 2],
+        [NaN, NaN, Infinity],
+        [/x/, /x/, /x/i],
+        ['a', 'a', 'A']
+      ];
+
+      lodashStable.each(values, function(vals) {
+        if (!isNpm) {
+          var wrapped1 = _(vals[0]),
+              wrapped2 = _(vals[1]),
+              actual = wrapped1.isEqual(wrapped2);
+
+          assert.strictEqual(actual, true);
+          assert.strictEqual(_.isEqual(_(actual), _(true)), true);
+
+          wrapped1 = _(vals[0]);
+          wrapped2 = _(vals[2]);
+
+          actual = wrapped1.isEqual(wrapped2);
+          assert.strictEqual(actual, false);
+          assert.strictEqual(_.isEqual(_(actual), _(false)), true);
+        }
+        else {
+          skipAssert(assert, 4);
+        }
+      });
+    });
+
+    QUnit.test('should compare wrapped and non-wrapped values', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var object1 = _({ 'a': 1, 'b': 2 }),
+            object2 = { 'a': 1, 'b': 2 };
+
+        assert.strictEqual(object1.isEqual(object2), true);
+        assert.strictEqual(_.isEqual(object1, object2), true);
+
+        object1 = _({ 'a': 1, 'b': 2 });
+        object2 = { 'a': 1, 'b': 1 };
+
+        assert.strictEqual(object1.isEqual(object2), false);
+        assert.strictEqual(_.isEqual(object1, object2), false);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_('a').isEqual('a'), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_('a').chain().isEqual('a') instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isEqualWith');
+
+  (function() {
+    QUnit.test('should provide the correct `customizer` arguments', function(assert) {
+      assert.expect(1);
+
+      var argsList = [],
+          object1 = { 'a': [1, 2], 'b': null },
+          object2 = { 'a': [1, 2], 'b': null };
+
+      object1.b = object2;
+      object2.b = object1;
+
+      var expected = [
+        [object1, object2],
+        [object1.a, object2.a, 'a', object1, object2],
+        [object1.a[0], object2.a[0], 0, object1.a, object2.a],
+        [object1.a[1], object2.a[1], 1, object1.a, object2.a],
+        [object1.b, object2.b, 'b', object1.b, object2.b],
+        [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
+        [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
+        [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
+        [object1.b.b, object2.b.b, 'b', object1.b.b, object2.b.b]
+      ];
+
+      _.isEqualWith(object1, object2, function(assert) {
+        var length = arguments.length,
+            args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
+
+        argsList.push(args);
+      });
+
+      assert.deepEqual(argsList, expected);
+    });
+
+    QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.isEqualWith('a', 'a', noop), true);
+      assert.strictEqual(_.isEqualWith(['a'], ['a'], noop), true);
+      assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, noop), true);
+    });
+
+    QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
+      assert.expect(3);
+
+      var customizer = function(value) {
+        return _.isString(value) || undefined;
+      };
+
+      assert.strictEqual(_.isEqualWith('a', 'b', customizer), true);
+      assert.strictEqual(_.isEqualWith(['a'], ['b'], customizer), true);
+      assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
+    });
+
+    QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
+      assert.expect(3);
+
+      var customizer = function(value) {
+        return _.isString(value) ? false : undefined;
+      };
+
+      assert.strictEqual(_.isEqualWith('a', 'a', customizer), false);
+      assert.strictEqual(_.isEqualWith(['a'], ['a'], customizer), false);
+      assert.strictEqual(_.isEqualWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
+    });
+
+    QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
+      assert.expect(2);
+
+      var actual = _.isEqualWith('a', 'b', alwaysC);
+      assert.strictEqual(actual, true);
+
+      var values = _.without(falsey, undefined),
+          expected = lodashStable.map(values, alwaysFalse);
+
+      actual = [];
+      lodashStable.each(values, function(value) {
+        actual.push(_.isEqualWith('a', 'a', lodashStable.constant(value)));
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should ensure `customizer` is a function', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3],
+          eq = _.partial(_.isEqualWith, array),
+          actual = lodashStable.map([array, [1, 0, 3]], eq);
+
+      assert.deepEqual(actual, [true, false]);
+    });
+
+    QUnit.test('should call `customizer` for values maps and sets', function(assert) {
+      assert.expect(2);
+
+      var value = { 'a': { 'b': 2 } };
+
+      if (Map) {
+        var map1 = new Map;
+        map1.set('a', value);
+
+        var map2 = new Map;
+        map2.set('a', value);
+      }
+      if (Set) {
+        var set1 = new Set;
+        set1.add(value);
+
+        var set2 = new Set;
+        set2.add(value);
+      }
+      lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
+        if (pair[0]) {
+          var argsList = [],
+              array = _.toArray(pair[0]);
+
+          var expected = [
+            [pair[0], pair[1]],
+            [array[0], array[0], 0, array, array],
+            [array[0][0], array[0][0], 0, array[0], array[0]],
+            [array[0][1], array[0][1], 1, array[0], array[0]]
+          ];
+
+          if (index) {
+            expected.length = 2;
+          }
+          _.isEqualWith(pair[0], pair[1], function() {
+            var length = arguments.length,
+                args = slice.call(arguments, 0, length - (length > 2 ? 1 : 0));
+
+            argsList.push(args);
+          });
+
+          assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isError');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for error objects', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(errors, alwaysTrue);
+
+      var actual = lodashStable.map(errors, function(error) {
+        return _.isError(error) === true;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` for subclassed values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isError(new CustomError('x')), true);
+    });
+
+    QUnit.test('should return `false` for non error objects', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isError(value) : _.isError();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isError(args), false);
+      assert.strictEqual(_.isError([1, 2, 3]), false);
+      assert.strictEqual(_.isError(true), false);
+      assert.strictEqual(_.isError(new Date), false);
+      assert.strictEqual(_.isError(_), false);
+      assert.strictEqual(_.isError(slice), false);
+      assert.strictEqual(_.isError({ 'a': 1 }), false);
+      assert.strictEqual(_.isError(1), false);
+      assert.strictEqual(_.isError(/x/), false);
+      assert.strictEqual(_.isError('a'), false);
+      assert.strictEqual(_.isError(symbol), false);
+    });
+
+    QUnit.test('should work with an error object from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.errors) {
+        var expected = lodashStable.map(realm.errors, alwaysTrue);
+
+        var actual = lodashStable.map(realm.errors, function(error) {
+          return _.isError(error) === true;
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isFinite');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for finite values', function(assert) {
+      assert.expect(1);
+
+      var values = [0, 1, 3.14, -1],
+          expected = lodashStable.map(values, alwaysTrue),
+          actual = lodashStable.map(values, _.isFinite);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-finite values', function(assert) {
+      assert.expect(1);
+
+      var values = [NaN, Infinity, -Infinity, Object(1)],
+          expected = lodashStable.map(values, alwaysFalse),
+          actual = lodashStable.map(values, _.isFinite);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-numeric values', function(assert) {
+      assert.expect(10);
+
+      var values = [undefined, [], true, '', ' ', '2px'],
+          expected = lodashStable.map(values, alwaysFalse),
+          actual = lodashStable.map(values, _.isFinite);
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isFinite(args), false);
+      assert.strictEqual(_.isFinite([1, 2, 3]), false);
+      assert.strictEqual(_.isFinite(true), false);
+      assert.strictEqual(_.isFinite(new Date), false);
+      assert.strictEqual(_.isFinite(new Error), false);
+      assert.strictEqual(_.isFinite({ 'a': 1 }), false);
+      assert.strictEqual(_.isFinite(/x/), false);
+      assert.strictEqual(_.isFinite('a'), false);
+      assert.strictEqual(_.isFinite(symbol), false);
+    });
+
+    QUnit.test('should return `false` for numeric string values', function(assert) {
+      assert.expect(1);
+
+      var values = ['2', '0', '08'],
+          expected = lodashStable.map(values, alwaysFalse),
+          actual = lodashStable.map(values, _.isFinite);
+
+      assert.deepEqual(actual, expected);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isFunction');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for functions', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isFunction(_), true);
+      assert.strictEqual(_.isFunction(slice), true);
+    });
+
+    QUnit.test('should return `true` for generator functions', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isFunction(generator), typeof generator == 'function');
+    });
+
+    QUnit.test('should return `true` for array view constructors', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(arrayViews, function(type) {
+        return objToString.call(root[type]) == funcTag;
+      });
+
+      var actual = lodashStable.map(arrayViews, function(type) {
+        return _.isFunction(root[type]);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-functions', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isFunction(value) : _.isFunction();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isFunction(args), false);
+      assert.strictEqual(_.isFunction([1, 2, 3]), false);
+      assert.strictEqual(_.isFunction(true), false);
+      assert.strictEqual(_.isFunction(new Date), false);
+      assert.strictEqual(_.isFunction(new Error), false);
+      assert.strictEqual(_.isFunction({ 'a': 1 }), false);
+      assert.strictEqual(_.isFunction(1), false);
+      assert.strictEqual(_.isFunction(/x/), false);
+      assert.strictEqual(_.isFunction('a'), false);
+      assert.strictEqual(_.isFunction(symbol), false);
+
+      if (document) {
+        assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false);
+      } else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work with host objects in IE 8 document mode (test in IE 11)', function(assert) {
+      assert.expect(2);
+
+      // Trigger a Chakra JIT bug.
+      // See https://github.com/jashkenas/underscore/issues/1621.
+      lodashStable.each([body, xml], function(object) {
+        if (object) {
+          lodashStable.times(100, _.isFunction);
+          assert.strictEqual(_.isFunction(object), false);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    QUnit.test('should work with a function from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.function) {
+        assert.strictEqual(_.isFunction(realm.function), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('isInteger methods');
+
+  lodashStable.each(['isInteger', 'isSafeInteger'], function(methodName) {
+    var args = arguments,
+        func = _[methodName],
+        isSafe = methodName == 'isSafeInteger';
+
+    QUnit.test('`_.' + methodName + '` should return `true` for integer values', function(assert) {
+      assert.expect(2);
+
+      var values = [-1, 0, 1],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(value);
+      });
+
+      assert.deepEqual(actual, expected);
+      assert.strictEqual(func(MAX_INTEGER), !isSafe);
+    });
+
+    QUnit.test('should return `false` for non-integer number values', function(assert) {
+      assert.expect(1);
+
+      var values = [NaN, Infinity, -Infinity, Object(1), 3.14],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-numeric values', function(assert) {
+      assert.expect(10);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === 0;
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? func(value) : func();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(func(args), false);
+      assert.strictEqual(func([1, 2, 3]), false);
+      assert.strictEqual(func(true), false);
+      assert.strictEqual(func(new Date), false);
+      assert.strictEqual(func(new Error), false);
+      assert.strictEqual(func({ 'a': 1 }), false);
+      assert.strictEqual(func(/x/), false);
+      assert.strictEqual(func('a'), false);
+      assert.strictEqual(func(symbol), false);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isLength');
+
+  (function() {
+    QUnit.test('should return `true` for lengths', function(assert) {
+      assert.expect(1);
+
+      var values = [0, 3, MAX_SAFE_INTEGER],
+          expected = lodashStable.map(values, alwaysTrue),
+          actual = lodashStable.map(values, _.isLength);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-lengths', function(assert) {
+      assert.expect(1);
+
+      var values = [-1, '1', 1.1, MAX_SAFE_INTEGER + 1],
+          expected = lodashStable.map(values, alwaysFalse),
+          actual = lodashStable.map(values, _.isLength);
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isMap');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for maps', function(assert) {
+      assert.expect(1);
+
+      if (Map) {
+        assert.strictEqual(_.isMap(map), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non-maps', function(assert) {
+      assert.expect(14);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isMap(value) : _.isMap();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isMap(args), false);
+      assert.strictEqual(_.isMap([1, 2, 3]), false);
+      assert.strictEqual(_.isMap(true), false);
+      assert.strictEqual(_.isMap(new Date), false);
+      assert.strictEqual(_.isMap(new Error), false);
+      assert.strictEqual(_.isMap(_), false);
+      assert.strictEqual(_.isMap(slice), false);
+      assert.strictEqual(_.isMap({ 'a': 1 }), false);
+      assert.strictEqual(_.isMap(1), false);
+      assert.strictEqual(_.isMap(/x/), false);
+      assert.strictEqual(_.isMap('a'), false);
+      assert.strictEqual(_.isMap(symbol), false);
+      assert.strictEqual(_.isMap(weakMap), false);
+    });
+
+    QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
+      assert.expect(1);
+
+      var values = [false, true],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.isMap({ 'constructor': value });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with maps from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.map) {
+        assert.strictEqual(_.isMap(realm.map), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isMatch');
+
+  (function() {
+    QUnit.test('should perform a deep comparison between `object` and `source`', function(assert) {
+      assert.expect(5);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 };
+      assert.strictEqual(_.isMatch(object, { 'a': 1 }), true);
+      assert.strictEqual(_.isMatch(object, { 'b': 1 }), false);
+      assert.strictEqual(_.isMatch(object, { 'a': 1, 'c': 3 }), true);
+      assert.strictEqual(_.isMatch(object, { 'c': 3, 'd': 4 }), false);
+
+      object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
+      assert.strictEqual(_.isMatch(object, { 'a': { 'b': { 'c': 1 } } }), true);
+    });
+
+    QUnit.test('should match inherited string keyed `object` properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      assert.strictEqual(_.isMatch({ 'a': new Foo }, { 'a': { 'b': 2 } }), true);
+    });
+
+    QUnit.test('should not match by inherited `source` properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
+          source = new Foo,
+          expected = lodashStable.map(objects, alwaysTrue);
+
+      var actual = lodashStable.map(objects, function(object) {
+        return _.isMatch(object, source);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should compare a variety of `source` property values', function(assert) {
+      assert.expect(2);
+
+      var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
+          object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } };
+
+      assert.strictEqual(_.isMatch(object1, object1), true);
+      assert.strictEqual(_.isMatch(object1, object2), false);
+    });
+
+    QUnit.test('should match `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      var object1 = { 'a': -0 },
+          object2 = { 'a': 0 };
+
+      assert.strictEqual(_.isMatch(object1, object2), true);
+      assert.strictEqual(_.isMatch(object2, object1), true);
+    });
+
+    QUnit.test('should compare functions by reference', function(assert) {
+      assert.expect(3);
+
+      var object1 = { 'a': lodashStable.noop },
+          object2 = { 'a': noop },
+          object3 = { 'a': {} };
+
+      assert.strictEqual(_.isMatch(object1, object1), true);
+      assert.strictEqual(_.isMatch(object2, object1), false);
+      assert.strictEqual(_.isMatch(object3, object1), false);
+    });
+
+    QUnit.test('should work with a function for `object`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.a = { 'b': 1, 'c': 2 };
+
+      assert.strictEqual(_.isMatch(Foo, { 'a': { 'b': 1 } }), true);
+    });
+
+    QUnit.test('should work with a function for `source`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.a = 1;
+      Foo.b = function() {};
+      Foo.c = 3;
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }];
+
+      var actual = lodashStable.map(objects, function(object) {
+        return _.isMatch(object, Foo);
+      });
+
+      assert.deepEqual(actual, [false, true]);
+    });
+
+    QUnit.test('should work with a non-plain `object`', function(assert) {
+      assert.expect(1);
+
+      function Foo(object) { lodashStable.assign(this, object); }
+
+      var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) });
+      assert.strictEqual(_.isMatch(object, { 'a': { 'b': 1 } }), true);
+    });
+
+    QUnit.test('should partial match arrays', function(assert) {
+      assert.expect(3);
+
+      var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
+          source = { 'a': ['d'] },
+          predicate = function(object) { return _.isMatch(object, source); },
+          actual = lodashStable.filter(objects, predicate);
+
+      assert.deepEqual(actual, [objects[1]]);
+
+      source = { 'a': ['b', 'd'] };
+      actual = lodashStable.filter(objects, predicate);
+
+      assert.deepEqual(actual, []);
+
+      source = { 'a': ['d', 'b'] };
+      actual = lodashStable.filter(objects, predicate);
+      assert.deepEqual(actual, []);
+    });
+
+    QUnit.test('should partial match arrays of objects', function(assert) {
+      assert.expect(1);
+
+      var source = { 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] };
+
+      var objects = [
+        { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
+        { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
+      ];
+
+      var actual = lodashStable.filter(objects, function(object) {
+        return _.isMatch(object, source);
+      });
+
+      assert.deepEqual(actual, [objects[0]]);
+    });
+
+    QUnit.test('should partial match maps', function(assert) {
+      assert.expect(3);
+
+      if (Map) {
+        var objects = [{ 'a': new Map }, { 'a': new Map }];
+        objects[0].a.set('a', 1);
+        objects[1].a.set('a', 1);
+        objects[1].a.set('b', 2);
+
+        var map = new Map;
+        map.set('b', 2);
+
+        var source = { 'a': map },
+            predicate = function(object) { return _.isMatch(object, source); },
+            actual = lodashStable.filter(objects, predicate);
+
+        assert.deepEqual(actual, [objects[1]]);
+
+        map['delete']('b');
+        actual = lodashStable.filter(objects, predicate);
+
+        assert.deepEqual(actual, objects);
+
+        map.set('c', 3);
+        actual = lodashStable.filter(objects, predicate);
+
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should partial match sets', function(assert) {
+      assert.expect(3);
+
+      if (Set) {
+        var objects = [{ 'a': new Set }, { 'a': new Set }];
+        objects[0].a.add(1);
+        objects[1].a.add(1);
+        objects[1].a.add(2);
+
+        var set = new Set;
+        set.add(2);
+
+        var source = { 'a': set },
+            predicate = function(object) { return _.isMatch(object, source); },
+            actual = lodashStable.filter(objects, predicate);
+
+        assert.deepEqual(actual, [objects[1]]);
+
+        set['delete'](2);
+        actual = lodashStable.filter(objects, predicate);
+
+        assert.deepEqual(actual, objects);
+
+        set.add(3);
+        actual = lodashStable.filter(objects, predicate);
+
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should match `undefined` values', function(assert) {
+      assert.expect(3);
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
+          source = { 'b': undefined },
+          predicate = function(object) { return _.isMatch(object, source); },
+          actual = lodashStable.map(objects, predicate),
+          expected = [false, false, true];
+
+      assert.deepEqual(actual, expected);
+
+      source = { 'a': 1, 'b': undefined };
+      actual = lodashStable.map(objects, predicate);
+
+      assert.deepEqual(actual, expected);
+
+      objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
+      source = { 'a': { 'c': undefined } };
+      actual = lodashStable.map(objects, predicate);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should match `undefined` values on primitives', function(assert) {
+      assert.expect(3);
+
+      numberProto.a = 1;
+      numberProto.b = undefined;
+
+      try {
+        assert.strictEqual(_.isMatch(1, { 'b': undefined }), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      try {
+        assert.strictEqual(_.isMatch(1, { 'a': 1, 'b': undefined }), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      numberProto.a = { 'b': 1, 'c': undefined };
+      try {
+        assert.strictEqual(_.isMatch(1, { 'a': { 'c': undefined } }), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      delete numberProto.a;
+      delete numberProto.b;
+    });
+
+    QUnit.test('should return `false` when `object` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [null, undefined],
+          expected = lodashStable.map(values, alwaysFalse),
+          source = { 'a': 1 };
+
+      var actual = lodashStable.map(values, function(value) {
+        try {
+          return _.isMatch(value, source);
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
+      assert.expect(1);
+
+      var values = [null, undefined],
+          expected = lodashStable.map(values, alwaysTrue),
+          source = {};
+
+      var actual = lodashStable.map(values, function(value) {
+        try {
+          return _.isMatch(value, source);
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1 },
+          expected = lodashStable.map(empties, alwaysTrue);
+
+      var actual = lodashStable.map(empties, function(value) {
+        return _.isMatch(object, value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
+          source = { 'a': [], 'b': {} };
+
+      var actual = lodashStable.filter(objects, function(object) {
+        return _.isMatch(object, source);
+      });
+
+      assert.deepEqual(actual, objects);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isMatchWith');
+
+  (function() {
+    QUnit.test('should provide the correct `customizer` arguments', function(assert) {
+      assert.expect(1);
+
+      var argsList = [],
+          object1 = { 'a': [1, 2], 'b': null },
+          object2 = { 'a': [1, 2], 'b': null };
+
+      object1.b = object2;
+      object2.b = object1;
+
+      var expected = [
+        [object1.a, object2.a, 'a', object1, object2],
+        [object1.a[0], object2.a[0], 0, object1.a, object2.a],
+        [object1.a[1], object2.a[1], 1, object1.a, object2.a],
+        [object1.b, object2.b, 'b', object1, object2],
+        [object1.b.a, object2.b.a, 'a', object1.b, object2.b],
+        [object1.b.a[0], object2.b.a[0], 0, object1.b.a, object2.b.a],
+        [object1.b.a[1], object2.b.a[1], 1, object1.b.a, object2.b.a],
+        [object1.b.b, object2.b.b, 'b', object1.b, object2.b],
+        [object1.b.b.a, object2.b.b.a, 'a', object1.b.b, object2.b.b],
+        [object1.b.b.a[0], object2.b.b.a[0], 0, object1.b.b.a, object2.b.b.a],
+        [object1.b.b.a[1], object2.b.b.a[1], 1, object1.b.b.a, object2.b.b.a],
+        [object1.b.b.b, object2.b.b.b, 'b', object1.b.b, object2.b.b]
+      ];
+
+      _.isMatchWith(object1, object2, function(assert) {
+        argsList.push(slice.call(arguments, 0, -1));
+      });
+
+      assert.deepEqual(argsList, expected);
+    });
+
+    QUnit.test('should handle comparisons if `customizer` returns `undefined`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isMatchWith({ 'a': 1 }, { 'a': 1 }, noop), true);
+    });
+
+    QUnit.test('should not handle comparisons if `customizer` returns `true`', function(assert) {
+      assert.expect(2);
+
+      var customizer = function(value) {
+        return _.isString(value) || undefined;
+      };
+
+      assert.strictEqual(_.isMatchWith(['a'], ['b'], customizer), true);
+      assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'b' }, customizer), true);
+    });
+
+    QUnit.test('should not handle comparisons if `customizer` returns `false`', function(assert) {
+      assert.expect(2);
+
+      var customizer = function(value) {
+        return _.isString(value) ? false : undefined;
+      };
+
+      assert.strictEqual(_.isMatchWith(['a'], ['a'], customizer), false);
+      assert.strictEqual(_.isMatchWith({ '0': 'a' }, { '0': 'a' }, customizer), false);
+    });
+
+    QUnit.test('should return a boolean value even if `customizer` does not', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1 },
+          actual = _.isMatchWith(object, { 'a': 1 }, alwaysA);
+
+      assert.strictEqual(actual, true);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      actual = [];
+      lodashStable.each(falsey, function(value) {
+        actual.push(_.isMatchWith(object, { 'a': 2 }, lodashStable.constant(value)));
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should ensure `customizer` is a function', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1 },
+          matches = _.partial(_.isMatchWith, object),
+          actual = lodashStable.map([object, { 'a': 2 }], matches);
+
+      assert.deepEqual(actual, [true, false]);
+    });
+
+    QUnit.test('should call `customizer` for values maps and sets', function(assert) {
+      assert.expect(2);
+
+      var value = { 'a': { 'b': 2 } };
+
+      if (Map) {
+        var map1 = new Map;
+        map1.set('a', value);
+
+        var map2 = new Map;
+        map2.set('a', value);
+      }
+      if (Set) {
+        var set1 = new Set;
+        set1.add(value);
+
+        var set2 = new Set;
+        set2.add(value);
+      }
+      lodashStable.each([[map1, map2], [set1, set2]], function(pair, index) {
+        if (pair[0]) {
+          var argsList = [],
+              array = _.toArray(pair[0]),
+              object1 = { 'a': pair[0] },
+              object2 = { 'a': pair[1] };
+
+          var expected = [
+            [pair[0], pair[1], 'a', object1, object2],
+            [array[0], array[0], 0, array, array],
+            [array[0][0], array[0][0], 0, array[0], array[0]],
+            [array[0][1], array[0][1], 1, array[0], array[0]]
+          ];
+
+          if (index) {
+            expected.length = 2;
+          }
+          _.isMatchWith({ 'a': pair[0] }, { 'a': pair[1] }, function() {
+            argsList.push(slice.call(arguments, 0, -1));
+          });
+
+          assert.deepEqual(argsList, expected, index ? 'Set' : 'Map');
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isNaN');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for NaNs', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isNaN(NaN), true);
+      assert.strictEqual(_.isNaN(Object(NaN)), true);
+    });
+
+    QUnit.test('should return `false` for non-NaNs', function(assert) {
+      assert.expect(14);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value !== value;
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isNaN(value) : _.isNaN();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isNaN(args), false);
+      assert.strictEqual(_.isNaN([1, 2, 3]), false);
+      assert.strictEqual(_.isNaN(true), false);
+      assert.strictEqual(_.isNaN(new Date), false);
+      assert.strictEqual(_.isNaN(new Error), false);
+      assert.strictEqual(_.isNaN(_), false);
+      assert.strictEqual(_.isNaN(slice), false);
+      assert.strictEqual(_.isNaN({ 'a': 1 }), false);
+      assert.strictEqual(_.isNaN(1), false);
+      assert.strictEqual(_.isNaN(Object(1)), false);
+      assert.strictEqual(_.isNaN(/x/), false);
+      assert.strictEqual(_.isNaN('a'), false);
+      assert.strictEqual(_.isNaN(symbol), false);
+    });
+
+    QUnit.test('should work with `NaN` from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.object) {
+        assert.strictEqual(_.isNaN(realm.nan), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isNative');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for native methods', function(assert) {
+      assert.expect(1);
+
+      var values = [Array, body && body.cloneNode, create, root.encodeURI, Promise, slice, Uint8Array],
+          expected = lodashStable.map(values, Boolean),
+          actual = lodashStable.map(values, _.isNative);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non-native methods', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isNative(value) : _.isNative();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isNative(args), false);
+      assert.strictEqual(_.isNative([1, 2, 3]), false);
+      assert.strictEqual(_.isNative(true), false);
+      assert.strictEqual(_.isNative(new Date), false);
+      assert.strictEqual(_.isNative(new Error), false);
+      assert.strictEqual(_.isNative(_), false);
+      assert.strictEqual(_.isNative({ 'a': 1 }), false);
+      assert.strictEqual(_.isNative(1), false);
+      assert.strictEqual(_.isNative(/x/), false);
+      assert.strictEqual(_.isNative('a'), false);
+      assert.strictEqual(_.isNative(symbol), false);
+    });
+
+    QUnit.test('should work with native functions from another realm', function(assert) {
+      assert.expect(2);
+
+      if (realm.element) {
+        assert.strictEqual(_.isNative(realm.element.cloneNode), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+      if (realm.object) {
+        assert.strictEqual(_.isNative(realm.object.valueOf), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isNil');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for nullish values', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.isNil(null), true);
+      assert.strictEqual(_.isNil(), true);
+      assert.strictEqual(_.isNil(undefined), true);
+    });
+
+    QUnit.test('should return `false` for non-nullish values', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value == null;
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isNil(value) : _.isNil();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isNil(args), false);
+      assert.strictEqual(_.isNil([1, 2, 3]), false);
+      assert.strictEqual(_.isNil(true), false);
+      assert.strictEqual(_.isNil(new Date), false);
+      assert.strictEqual(_.isNil(new Error), false);
+      assert.strictEqual(_.isNil(_), false);
+      assert.strictEqual(_.isNil(slice), false);
+      assert.strictEqual(_.isNil({ 'a': 1 }), false);
+      assert.strictEqual(_.isNil(1), false);
+      assert.strictEqual(_.isNil(/x/), false);
+      assert.strictEqual(_.isNil('a'), false);
+
+      if (Symbol) {
+        assert.strictEqual(_.isNil(symbol), false);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work with nulls from another realm', function(assert) {
+      assert.expect(2);
+
+      if (realm.object) {
+        assert.strictEqual(_.isNil(realm.null), true);
+        assert.strictEqual(_.isNil(realm.undefined), true);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isNull');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for `null` values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isNull(null), true);
+    });
+
+    QUnit.test('should return `false` for non `null` values', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === null;
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isNull(value) : _.isNull();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isNull(args), false);
+      assert.strictEqual(_.isNull([1, 2, 3]), false);
+      assert.strictEqual(_.isNull(true), false);
+      assert.strictEqual(_.isNull(new Date), false);
+      assert.strictEqual(_.isNull(new Error), false);
+      assert.strictEqual(_.isNull(_), false);
+      assert.strictEqual(_.isNull(slice), false);
+      assert.strictEqual(_.isNull({ 'a': 1 }), false);
+      assert.strictEqual(_.isNull(1), false);
+      assert.strictEqual(_.isNull(/x/), false);
+      assert.strictEqual(_.isNull('a'), false);
+      assert.strictEqual(_.isNull(symbol), false);
+    });
+
+    QUnit.test('should work with nulls from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.object) {
+        assert.strictEqual(_.isNull(realm.null), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isNumber');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.isNumber(0), true);
+      assert.strictEqual(_.isNumber(Object(0)), true);
+      assert.strictEqual(_.isNumber(NaN), true);
+    });
+
+    QUnit.test('should return `false` for non-numbers', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return typeof value == 'number';
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isNumber(value) : _.isNumber();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isNumber(args), false);
+      assert.strictEqual(_.isNumber([1, 2, 3]), false);
+      assert.strictEqual(_.isNumber(true), false);
+      assert.strictEqual(_.isNumber(new Date), false);
+      assert.strictEqual(_.isNumber(new Error), false);
+      assert.strictEqual(_.isNumber(_), false);
+      assert.strictEqual(_.isNumber(slice), false);
+      assert.strictEqual(_.isNumber({ 'a': 1 }), false);
+      assert.strictEqual(_.isNumber(/x/), false);
+      assert.strictEqual(_.isNumber('a'), false);
+      assert.strictEqual(_.isNumber(symbol), false);
+    });
+
+    QUnit.test('should work with numbers from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.number) {
+        assert.strictEqual(_.isNumber(realm.number), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should avoid `[xpconnect wrapped native prototype]` in Firefox', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.isNumber(+'2'), true);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isObject');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for objects', function(assert) {
+      assert.expect(13);
+
+      assert.strictEqual(_.isObject(args), true);
+      assert.strictEqual(_.isObject([1, 2, 3]), true);
+      assert.strictEqual(_.isObject(Object(false)), true);
+      assert.strictEqual(_.isObject(new Date), true);
+      assert.strictEqual(_.isObject(new Error), true);
+      assert.strictEqual(_.isObject(_), true);
+      assert.strictEqual(_.isObject(slice), true);
+      assert.strictEqual(_.isObject({ 'a': 1 }), true);
+      assert.strictEqual(_.isObject(Object(0)), true);
+      assert.strictEqual(_.isObject(/x/), true);
+      assert.strictEqual(_.isObject(Object('a')), true);
+
+      if (document) {
+        assert.strictEqual(_.isObject(body), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+      if (Symbol) {
+        assert.strictEqual(_.isObject(Object(symbol)), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non-objects', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat(true, 1, 'a', symbol),
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.isObject(value) : _.isObject();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with objects from another realm', function(assert) {
+      assert.expect(8);
+
+      if (realm.element) {
+        assert.strictEqual(_.isObject(realm.element), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+      if (realm.object) {
+        assert.strictEqual(_.isObject(realm.boolean), true);
+        assert.strictEqual(_.isObject(realm.date), true);
+        assert.strictEqual(_.isObject(realm.function), true);
+        assert.strictEqual(_.isObject(realm.number), true);
+        assert.strictEqual(_.isObject(realm.object), true);
+        assert.strictEqual(_.isObject(realm.regexp), true);
+        assert.strictEqual(_.isObject(realm.string), true);
+      }
+      else {
+        skipAssert(assert, 7);
+      }
+    });
+
+    QUnit.test('should avoid V8 bug #2291 (test in Chrome 19-20)', function(assert) {
+      assert.expect(1);
+
+      // Trigger a V8 JIT bug.
+      // See https://code.google.com/p/v8/issues/detail?id=2291.
+      var object = {};
+
+      // First, have a comparison statement.
+      object == object;
+
+      // Then perform the check with `object`.
+      _.isObject(object);
+
+      assert.strictEqual(_.isObject('a'), false);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isObjectLike');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for objects', function(assert) {
+      assert.expect(9);
+
+      assert.strictEqual(_.isObjectLike(args), true);
+      assert.strictEqual(_.isObjectLike([1, 2, 3]), true);
+      assert.strictEqual(_.isObjectLike(Object(false)), true);
+      assert.strictEqual(_.isObjectLike(new Date), true);
+      assert.strictEqual(_.isObjectLike(new Error), true);
+      assert.strictEqual(_.isObjectLike({ 'a': 1 }), true);
+      assert.strictEqual(_.isObjectLike(Object(0)), true);
+      assert.strictEqual(_.isObjectLike(/x/), true);
+      assert.strictEqual(_.isObjectLike(Object('a')), true);
+    });
+
+    QUnit.test('should return `false` for non-objects', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat(true, _, slice, 1, 'a', symbol),
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.isObjectLike(value) : _.isObjectLike();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with objects from another realm', function(assert) {
+      assert.expect(6);
+
+      if (realm.object) {
+        assert.strictEqual(_.isObjectLike(realm.boolean), true);
+        assert.strictEqual(_.isObjectLike(realm.date), true);
+        assert.strictEqual(_.isObjectLike(realm.number), true);
+        assert.strictEqual(_.isObjectLike(realm.object), true);
+        assert.strictEqual(_.isObjectLike(realm.regexp), true);
+        assert.strictEqual(_.isObjectLike(realm.string), true);
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isPlainObject');
+
+  (function() {
+    var element = document && document.createElement('div');
+
+    QUnit.test('should detect plain objects', function(assert) {
+      assert.expect(5);
+
+      function Foo(a) {
+        this.a = 1;
+      }
+
+      assert.strictEqual(_.isPlainObject({}), true);
+      assert.strictEqual(_.isPlainObject({ 'a': 1 }), true);
+      assert.strictEqual(_.isPlainObject({ 'constructor': Foo }), true);
+      assert.strictEqual(_.isPlainObject([1, 2, 3]), false);
+      assert.strictEqual(_.isPlainObject(new Foo(1)), false);
+    });
+
+    QUnit.test('should return `true` for objects with a `[[Prototype]]` of `null`', function(assert) {
+      assert.expect(2);
+
+      if (create) {
+        var object = create(null);
+        assert.strictEqual(_.isPlainObject(object), true);
+
+        object.constructor = objectProto.constructor;
+        assert.strictEqual(_.isPlainObject(object), true);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should return `true` for plain objects with a custom `valueOf` property', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isPlainObject({ 'valueOf': 0 }), true);
+
+      if (element) {
+        var valueOf = element.valueOf;
+        element.valueOf = 0;
+
+        assert.strictEqual(_.isPlainObject(element), false);
+        element.valueOf = valueOf;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for objects with a custom `[[Prototype]]`', function(assert) {
+      assert.expect(1);
+
+      if (create) {
+        var object = create({ 'a': 1 });
+        assert.strictEqual(_.isPlainObject(object), false);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for DOM elements', function(assert) {
+      assert.expect(1);
+
+      if (element) {
+        assert.strictEqual(_.isPlainObject(element), false);
+      } else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for Object objects without a `toStringTag` of "Object"', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.isPlainObject(arguments), false);
+      assert.strictEqual(_.isPlainObject(Error), false);
+      assert.strictEqual(_.isPlainObject(Math), false);
+    });
+
+    QUnit.test('should return `false` for non-objects', function(assert) {
+      assert.expect(4);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isPlainObject(value) : _.isPlainObject();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isPlainObject(true), false);
+      assert.strictEqual(_.isPlainObject('a'), false);
+      assert.strictEqual(_.isPlainObject(symbol), false);
+    });
+
+    QUnit.test('should work with objects from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.object) {
+        assert.strictEqual(_.isPlainObject(realm.object), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isRegExp');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for regexes', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isRegExp(/x/), true);
+      assert.strictEqual(_.isRegExp(RegExp('x')), true);
+    });
+
+    QUnit.test('should return `false` for non-regexes', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isRegExp(value) : _.isRegExp();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isRegExp(args), false);
+      assert.strictEqual(_.isRegExp([1, 2, 3]), false);
+      assert.strictEqual(_.isRegExp(true), false);
+      assert.strictEqual(_.isRegExp(new Date), false);
+      assert.strictEqual(_.isRegExp(new Error), false);
+      assert.strictEqual(_.isRegExp(_), false);
+      assert.strictEqual(_.isRegExp(slice), false);
+      assert.strictEqual(_.isRegExp({ 'a': 1 }), false);
+      assert.strictEqual(_.isRegExp(1), false);
+      assert.strictEqual(_.isRegExp('a'), false);
+      assert.strictEqual(_.isRegExp(symbol), false);
+    });
+
+    QUnit.test('should work with regexes from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.regexp) {
+        assert.strictEqual(_.isRegExp(realm.regexp), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isSet');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for sets', function(assert) {
+      assert.expect(1);
+
+      if (Set) {
+        assert.strictEqual(_.isSet(set), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non-sets', function(assert) {
+      assert.expect(14);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isSet(value) : _.isSet();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isSet(args), false);
+      assert.strictEqual(_.isSet([1, 2, 3]), false);
+      assert.strictEqual(_.isSet(true), false);
+      assert.strictEqual(_.isSet(new Date), false);
+      assert.strictEqual(_.isSet(new Error), false);
+      assert.strictEqual(_.isSet(_), false);
+      assert.strictEqual(_.isSet(slice), false);
+      assert.strictEqual(_.isSet({ 'a': 1 }), false);
+      assert.strictEqual(_.isSet(1), false);
+      assert.strictEqual(_.isSet(/x/), false);
+      assert.strictEqual(_.isSet('a'), false);
+      assert.strictEqual(_.isSet(symbol), false);
+      assert.strictEqual(_.isSet(weakSet), false);
+    });
+
+    QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
+      assert.expect(1);
+
+      var values = [false, true],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.isSet({ 'constructor': value });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with weak sets from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.set) {
+        assert.strictEqual(_.isSet(realm.set), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isString');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for strings', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isString('a'), true);
+      assert.strictEqual(_.isString(Object('a')), true);
+    });
+
+    QUnit.test('should return `false` for non-strings', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === '';
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isString(value) : _.isString();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isString(args), false);
+      assert.strictEqual(_.isString([1, 2, 3]), false);
+      assert.strictEqual(_.isString(true), false);
+      assert.strictEqual(_.isString(new Date), false);
+      assert.strictEqual(_.isString(new Error), false);
+      assert.strictEqual(_.isString(_), false);
+      assert.strictEqual(_.isString(slice), false);
+      assert.strictEqual(_.isString({ '0': 1, 'length': 1 }), false);
+      assert.strictEqual(_.isString(1), false);
+      assert.strictEqual(_.isString(/x/), false);
+      assert.strictEqual(_.isString(symbol), false);
+    });
+
+    QUnit.test('should work with strings from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.string) {
+        assert.strictEqual(_.isString(realm.string), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isSymbol');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for symbols', function(assert) {
+      assert.expect(2);
+
+      if (Symbol) {
+        assert.strictEqual(_.isSymbol(symbol), true);
+        assert.strictEqual(_.isSymbol(Object(symbol)), true);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should return `false` for non-symbols', function(assert) {
+      assert.expect(12);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isSymbol(value) : _.isSymbol();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isSymbol(args), false);
+      assert.strictEqual(_.isSymbol([1, 2, 3]), false);
+      assert.strictEqual(_.isSymbol(true), false);
+      assert.strictEqual(_.isSymbol(new Date), false);
+      assert.strictEqual(_.isSymbol(new Error), false);
+      assert.strictEqual(_.isSymbol(_), false);
+      assert.strictEqual(_.isSymbol(slice), false);
+      assert.strictEqual(_.isSymbol({ '0': 1, 'length': 1 }), false);
+      assert.strictEqual(_.isSymbol(1), false);
+      assert.strictEqual(_.isSymbol(/x/), false);
+      assert.strictEqual(_.isSymbol('a'), false);
+    });
+
+    QUnit.test('should work with symbols from another realm', function(assert) {
+      assert.expect(1);
+
+      if (Symbol && realm.symbol) {
+        assert.strictEqual(_.isSymbol(realm.symbol), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isTypedArray');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for typed arrays', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(typedArrays, function(type) {
+        return type in root;
+      });
+
+      var actual = lodashStable.map(typedArrays, function(type) {
+        var Ctor = root[type];
+        return Ctor ? _.isTypedArray(new Ctor(new ArrayBuffer(8))) : false;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `false` for non typed arrays', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isTypedArray(value) : _.isTypedArray();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isTypedArray(args), false);
+      assert.strictEqual(_.isTypedArray([1, 2, 3]), false);
+      assert.strictEqual(_.isTypedArray(true), false);
+      assert.strictEqual(_.isTypedArray(new Date), false);
+      assert.strictEqual(_.isTypedArray(new Error), false);
+      assert.strictEqual(_.isTypedArray(_), false);
+      assert.strictEqual(_.isTypedArray(slice), false);
+      assert.strictEqual(_.isTypedArray({ 'a': 1 }), false);
+      assert.strictEqual(_.isTypedArray(1), false);
+      assert.strictEqual(_.isTypedArray(/x/), false);
+      assert.strictEqual(_.isTypedArray('a'), false);
+      assert.strictEqual(_.isTypedArray(symbol), false);
+    });
+
+    QUnit.test('should work with typed arrays from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.object) {
+        var props = lodashStable.invokeMap(typedArrays, 'toLowerCase');
+
+        var expected = lodashStable.map(props, function(key) {
+          return realm[key] !== undefined;
+        });
+
+        var actual = lodashStable.map(props, function(key) {
+          var value = realm[key];
+          return value ? _.isTypedArray(value) : false;
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isUndefined');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for `undefined` values', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.isUndefined(), true);
+      assert.strictEqual(_.isUndefined(undefined), true);
+    });
+
+    QUnit.test('should return `false` for non `undefined` values', function(assert) {
+      assert.expect(13);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined;
+      });
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isUndefined(value) : _.isUndefined();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isUndefined(args), false);
+      assert.strictEqual(_.isUndefined([1, 2, 3]), false);
+      assert.strictEqual(_.isUndefined(true), false);
+      assert.strictEqual(_.isUndefined(new Date), false);
+      assert.strictEqual(_.isUndefined(new Error), false);
+      assert.strictEqual(_.isUndefined(_), false);
+      assert.strictEqual(_.isUndefined(slice), false);
+      assert.strictEqual(_.isUndefined({ 'a': 1 }), false);
+      assert.strictEqual(_.isUndefined(1), false);
+      assert.strictEqual(_.isUndefined(/x/), false);
+      assert.strictEqual(_.isUndefined('a'), false);
+
+      if (Symbol) {
+        assert.strictEqual(_.isUndefined(symbol), false);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work with `undefined` from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.object) {
+        assert.strictEqual(_.isUndefined(realm.undefined), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isWeakMap');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for weak maps', function(assert) {
+      assert.expect(1);
+
+      if (WeakMap) {
+        assert.strictEqual(_.isWeakMap(weakMap), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non weak maps', function(assert) {
+      assert.expect(14);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isWeakMap(value) : _.isWeakMap();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isWeakMap(args), false);
+      assert.strictEqual(_.isWeakMap([1, 2, 3]), false);
+      assert.strictEqual(_.isWeakMap(true), false);
+      assert.strictEqual(_.isWeakMap(new Date), false);
+      assert.strictEqual(_.isWeakMap(new Error), false);
+      assert.strictEqual(_.isWeakMap(_), false);
+      assert.strictEqual(_.isWeakMap(slice), false);
+      assert.strictEqual(_.isWeakMap({ 'a': 1 }), false);
+      assert.strictEqual(_.isWeakMap(map), false);
+      assert.strictEqual(_.isWeakMap(1), false);
+      assert.strictEqual(_.isWeakMap(/x/), false);
+      assert.strictEqual(_.isWeakMap('a'), false);
+      assert.strictEqual(_.isWeakMap(symbol), false);
+    });
+
+    QUnit.test('should work for objects with a non-function `constructor` (test in IE 11)', function(assert) {
+      assert.expect(1);
+
+      var values = [false, true],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.isWeakMap({ 'constructor': value });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with weak maps from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.weakMap) {
+        assert.strictEqual(_.isWeakMap(realm.weakMap), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.isWeakSet');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should return `true` for weak sets', function(assert) {
+      assert.expect(1);
+
+      if (WeakSet) {
+        assert.strictEqual(_.isWeakSet(weakSet), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return `false` for non weak sets', function(assert) {
+      assert.expect(14);
+
+      var expected = lodashStable.map(falsey, alwaysFalse);
+
+      var actual = lodashStable.map(falsey, function(value, index) {
+        return index ? _.isWeakSet(value) : _.isWeakSet();
+      });
+
+      assert.deepEqual(actual, expected);
+
+      assert.strictEqual(_.isWeakSet(args), false);
+      assert.strictEqual(_.isWeakSet([1, 2, 3]), false);
+      assert.strictEqual(_.isWeakSet(true), false);
+      assert.strictEqual(_.isWeakSet(new Date), false);
+      assert.strictEqual(_.isWeakSet(new Error), false);
+      assert.strictEqual(_.isWeakSet(_), false);
+      assert.strictEqual(_.isWeakSet(slice), false);
+      assert.strictEqual(_.isWeakSet({ 'a': 1 }), false);
+      assert.strictEqual(_.isWeakSet(1), false);
+      assert.strictEqual(_.isWeakSet(/x/), false);
+      assert.strictEqual(_.isWeakSet('a'), false);
+      assert.strictEqual(_.isWeakSet(set), false);
+      assert.strictEqual(_.isWeakSet(symbol), false);
+    });
+
+    QUnit.test('should work with weak sets from another realm', function(assert) {
+      assert.expect(1);
+
+      if (realm.weakSet) {
+        assert.strictEqual(_.isWeakSet(realm.weakSet), true);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('isType checks');
+
+  (function() {
+    QUnit.test('should return `false` for subclassed values', function(assert) {
+      assert.expect(7);
+
+      var funcs = [
+        'isArray', 'isBoolean', 'isDate', 'isFunction',
+        'isNumber', 'isRegExp', 'isString'
+      ];
+
+      lodashStable.each(funcs, function(methodName) {
+        function Foo() {}
+        Foo.prototype = root[methodName.slice(2)].prototype;
+
+        var object = new Foo;
+        if (objToString.call(object) == objectTag) {
+          assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`');
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    QUnit.test('should not error on host objects (test in IE)', function(assert) {
+      assert.expect(26);
+
+      var funcs = [
+        'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isBoolean',
+        'isBuffer', 'isDate', 'isElement', 'isError', 'isFinite', 'isFunction',
+        'isInteger', 'isMap', 'isNaN', 'isNil', 'isNull', 'isNumber', 'isObject',
+        'isObjectLike', 'isRegExp', 'isSet', 'isSafeInteger', 'isString',
+        'isUndefined', 'isWeakMap', 'isWeakSet'
+      ];
+
+      lodashStable.each(funcs, function(methodName) {
+        if (xml) {
+          var pass = true;
+
+          try {
+            _[methodName](xml);
+          } catch (e) {
+            pass = false;
+          }
+          assert.ok(pass, '`_.' + methodName + '` should not error');
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.iteratee');
+
+  (function() {
+    QUnit.test('should provide arguments to `func`', function(assert) {
+      assert.expect(1);
+
+      var fn = function() { return slice.call(arguments); },
+          iteratee = _.iteratee(fn),
+          actual = iteratee('a', 'b', 'c', 'd', 'e', 'f');
+
+      assert.deepEqual(actual, ['a', 'b', 'c', 'd', 'e', 'f']);
+    });
+
+    QUnit.test('should return `_.identity` when `func` is nullish', function(assert) {
+      assert.expect(1);
+
+      var object = {},
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([!isNpm && _.identity, object]));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var identity = index ? _.iteratee(value) : _.iteratee();
+        return [!isNpm && identity, identity(object)];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an iteratee created by `_.matches` when `func` is an object', function(assert) {
+      assert.expect(2);
+
+      var matches = _.iteratee({ 'a': 1, 'b': 2 });
+      assert.strictEqual(matches({ 'a': 1, 'b': 2, 'c': 3 }), true);
+      assert.strictEqual(matches({ 'b': 2 }), false);
+    });
+
+    QUnit.test('should not change `_.matches` behavior if `source` is modified', function(assert) {
+      assert.expect(9);
+
+      var sources = [
+        { 'a': { 'b': 2, 'c': 3 } },
+        { 'a': 1, 'b': 2 },
+        { 'a': 1 }
+      ];
+
+      lodashStable.each(sources, function(source, index) {
+        var object = lodashStable.cloneDeep(source),
+            matches = _.iteratee(source);
+
+        assert.strictEqual(matches(object), true);
+
+        if (index) {
+          source.a = 2;
+          source.b = 1;
+          source.c = 3;
+        } else {
+          source.a.b = 1;
+          source.a.c = 2;
+          source.a.d = 3;
+        }
+        assert.strictEqual(matches(object), true);
+        assert.strictEqual(matches(source), false);
+      });
+    });
+
+    QUnit.test('should return an iteratee created by `_.matchesProperty` when `func` is an array', function(assert) {
+      assert.expect(3);
+
+      var array = ['a', undefined],
+          matches = _.iteratee([0, 'a']);
+
+      assert.strictEqual(matches(array), true);
+
+      matches = _.iteratee(['0', 'a']);
+      assert.strictEqual(matches(array), true);
+
+      matches = _.iteratee([1, undefined]);
+      assert.strictEqual(matches(array), true);
+    });
+
+    QUnit.test('should support deep paths for `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': { 'c': 1, 'd': 2 } } },
+          matches = _.iteratee(['a.b', { 'c': 1 }]);
+
+      assert.strictEqual(matches(object), true);
+    });
+
+    QUnit.test('should not change `_.matchesProperty` behavior if `source` is modified', function(assert) {
+      assert.expect(9);
+
+      var sources = [
+        { 'a': { 'b': 2, 'c': 3 } },
+        { 'a': 1, 'b': 2 },
+        { 'a': 1 }
+      ];
+
+      lodashStable.each(sources, function(source, index) {
+        var object = { 'a': lodashStable.cloneDeep(source) },
+            matches = _.iteratee(['a', source]);
+
+        assert.strictEqual(matches(object), true);
+
+        if (index) {
+          source.a = 2;
+          source.b = 1;
+          source.c = 3;
+        } else {
+          source.a.b = 1;
+          source.a.c = 2;
+          source.a.d = 3;
+        }
+        assert.strictEqual(matches(object), true);
+        assert.strictEqual(matches({ 'a': source }), false);
+      });
+    });
+
+    QUnit.test('should return an iteratee created by `_.property` when `func` is a number or string', function(assert) {
+      assert.expect(2);
+
+      var array = ['a'],
+          prop = _.iteratee(0);
+
+      assert.strictEqual(prop(array), 'a');
+
+      prop = _.iteratee('0');
+      assert.strictEqual(prop(array), 'a');
+    });
+
+    QUnit.test('should support deep paths for `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': 2 } },
+          prop = _.iteratee('a.b');
+
+      assert.strictEqual(prop(object), 2);
+    });
+
+    QUnit.test('should work with functions created by `_.partial` and `_.partialRight`', function(assert) {
+      assert.expect(2);
+
+      var fn = function() {
+        var result = [this.a];
+        push.apply(result, arguments);
+        return result;
+      };
+
+      var expected = [1, 2, 3],
+          object = { 'a': 1 , 'iteratee': _.iteratee(_.partial(fn, 2)) };
+
+      assert.deepEqual(object.iteratee(3), expected);
+
+      object.iteratee = _.iteratee(_.partialRight(fn, 3));
+      assert.deepEqual(object.iteratee(2), expected);
+    });
+
+    QUnit.test('should use internal `iteratee` if external is unavailable', function(assert) {
+      assert.expect(1);
+
+      var iteratee = _.iteratee;
+      delete _.iteratee;
+
+      assert.deepEqual(_.map([{ 'a': 1 }], 'a'), [1]);
+
+      _.iteratee = iteratee;
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var fn = function() { return this instanceof Number; },
+          array = [fn, fn, fn],
+          iteratees = lodashStable.map(array, _.iteratee),
+          expected = lodashStable.map(array, alwaysFalse);
+
+      var actual = lodashStable.map(iteratees, function(iteratee) {
+        return iteratee();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('custom `_.iteratee` methods');
+
+  (function() {
+    var array = ['one', 'two', 'three'],
+        getPropA = _.partial(_.property, 'a'),
+        getPropB = _.partial(_.property, 'b'),
+        getLength = _.partial(_.property, 'length'),
+        iteratee = _.iteratee;
+
+    var getSum = function() {
+      return function(result, object) {
+        return result + object.a;
+      };
+    };
+
+    var objects = [
+      { 'a': 0, 'b': 0 },
+      { 'a': 1, 'b': 0 },
+      { 'a': 1, 'b': 1 }
+    ];
+
+    QUnit.test('`_.countBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getLength;
+        assert.deepEqual(_.countBy(array), { '3': 2, '5': 1 });
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.differenceBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.deepEqual(_.differenceBy(objects, [objects[1]]), [objects[0]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.dropRightWhile` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.dropRightWhile(objects), objects.slice(0, 2));
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.dropWhile` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.dropWhile(objects.reverse()).reverse(), objects.reverse().slice(0, 2));
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.every` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.strictEqual(_.every(objects.slice(1)), true);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.filter` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var objects = [{ 'a': 0 }, { 'a': 1 }];
+
+        _.iteratee = getPropA;
+        assert.deepEqual(_.filter(objects), [objects[1]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.find` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.strictEqual(_.find(objects), objects[1]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.findIndex` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.strictEqual(_.findIndex(objects), 1);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.findLast` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.strictEqual(_.findLast(objects), objects[2]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.findLastIndex` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.strictEqual(_.findLastIndex(objects), 2);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.findKey` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.strictEqual(_.findKey(objects), '2');
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.findLastKey` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.strictEqual(_.findLastKey(objects), '2');
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.groupBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getLength;
+        assert.deepEqual(_.groupBy(array), { '3': ['one', 'two'], '5': ['three'] });
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.intersectionBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.deepEqual(_.intersectionBy(objects, [objects[2]]), [objects[1]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.keyBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getLength;
+        assert.deepEqual(_.keyBy(array), { '3': 'two', '5': 'three' });
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.map` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.deepEqual(_.map(objects), [0, 1, 1]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.mapKeys` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.mapKeys({ 'a': { 'b': 1 } }), { '1':  { 'b': 1 } });
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.mapValues` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.mapValues({ 'a': { 'b': 1 } }), { 'a': 1 });
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.maxBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.maxBy(objects), objects[2]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.meanBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.strictEqual(_.meanBy(objects), 2 / 3);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.minBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.minBy(objects), objects[0]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.partition` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }];
+
+        _.iteratee = getPropA;
+        assert.deepEqual(_.partition(objects), [objects.slice(0, 2), objects.slice(2)]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.pullAllBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.deepEqual(_.pullAllBy(objects.slice(), [{ 'a': 1, 'b': 0 }]), [objects[0]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.reduce` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getSum;
+        assert.strictEqual(_.reduce(objects, undefined, 0), 2);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.reduceRight` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getSum;
+        assert.strictEqual(_.reduceRight(objects, undefined, 0), 2);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.reject` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var objects = [{ 'a': 0 }, { 'a': 1 }];
+
+        _.iteratee = getPropA;
+        assert.deepEqual(_.reject(objects), [objects[0]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.remove` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var objects = [{ 'a': 0 }, { 'a': 1 }];
+
+        _.iteratee = getPropA;
+        _.remove(objects);
+        assert.deepEqual(objects, [{ 'a': 0 }]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.some` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.strictEqual(_.some(objects), true);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.sortBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.deepEqual(_.sortBy(objects.slice().reverse()), [objects[0], objects[2], objects[1]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.sortedIndexBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var objects = [{ 'a': 30 }, { 'a': 50 }];
+
+        _.iteratee = getPropA;
+        assert.strictEqual(_.sortedIndexBy(objects, { 'a': 40 }), 1);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.sortedLastIndexBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var objects = [{ 'a': 30 }, { 'a': 50 }];
+
+        _.iteratee = getPropA;
+        assert.strictEqual(_.sortedLastIndexBy(objects, { 'a': 40 }), 1);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.sumBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.strictEqual(_.sumBy(objects), 1);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.takeRightWhile` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.takeRightWhile(objects), objects.slice(2));
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.takeWhile` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.takeWhile(objects.reverse()), objects.reverse().slice(2));
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.transform` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = function() {
+          return function(result, object) {
+            result.sum += object.a;
+          };
+        };
+
+        assert.deepEqual(_.transform(objects, undefined, { 'sum': 0 }), { 'sum': 2 });
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.uniqBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.uniqBy(objects), [objects[0], objects[2]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.unionBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropB;
+        assert.deepEqual(_.unionBy(objects.slice(0, 1), [objects[2]]), [objects[0], objects[2]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.xorBy` should use `_.iteratee` internally', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        _.iteratee = getPropA;
+        assert.deepEqual(_.xorBy(objects, objects.slice(1)), [objects[0]]);
+        _.iteratee = iteratee;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.join');
+
+  (function() {
+    var array = ['a', 'b', 'c'];
+
+    QUnit.test('should return join all array elements into a string', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.join(array, '~'), 'a~b~c');
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _(array);
+        assert.strictEqual(wrapped.join('~'), 'a~b~c');
+        assert.strictEqual(wrapped.value(), array);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(array).chain().join('~') instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.keyBy');
+
+  (function() {
+    var array = [
+      { 'dir': 'left', 'code': 97 },
+      { 'dir': 'right', 'code': 100 }
+    ];
+
+    QUnit.test('should transform keys by `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } };
+
+      var actual = _.keyBy(array, function(object) {
+        return String.fromCharCode(object.code);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var array = [4, 6, 6],
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant({ '4': 4, '6': 6 }));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.keyBy(array, value) : _.keyBy(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } },
+          actual = _.keyBy(array, 'dir');
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should only add values to own, not inherited, properties', function(assert) {
+      assert.expect(2);
+
+      var actual = _.keyBy([6.1, 4.2, 6.3], function(n) {
+        return Math.floor(n) > 4 ? 'hasOwnProperty' : 'constructor';
+      });
+
+      assert.deepEqual(actual.constructor, 4.2);
+      assert.deepEqual(actual.hasOwnProperty, 6.3);
+    });
+
+    QUnit.test('should work with a number for `iteratee`', function(assert) {
+      assert.expect(2);
+
+      var array = [
+        [1, 'a'],
+        [2, 'a'],
+        [2, 'b']
+      ];
+
+      assert.deepEqual(_.keyBy(array, 0), { '1': [1, 'a'], '2': [2, 'b'] });
+      assert.deepEqual(_.keyBy(array, 1), { 'a': [2, 'a'], 'b': [2, 'b'] });
+    });
+
+    QUnit.test('should work with an object for `collection`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.keyBy({ 'a': 6.1, 'b': 4.2, 'c': 6.3 }, Math.floor);
+      assert.deepEqual(actual, { '4': 4.2, '6': 6.3 });
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(
+          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 2), LARGE_ARRAY_SIZE),
+          lodashStable.range(Math.floor(LARGE_ARRAY_SIZE / 1.5), LARGE_ARRAY_SIZE)
+        );
+
+        var actual = _(array).keyBy().map(square).filter(isEven).take().value();
+
+        assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven)));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('keys methods');
+
+  lodashStable.each(['keys', 'keysIn'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
+        func = _[methodName],
+        isKeys = methodName == 'keys';
+
+    QUnit.test('`_.' + methodName + '` should return the string keyed property names of `object`', function(assert) {
+      assert.expect(1);
+
+      var actual = func({ 'a': 1, 'b': 1 }).sort();
+
+      assert.deepEqual(actual, ['a', 'b']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var expected = isKeys ? ['a'] : ['a', 'b'],
+          actual = func(new Foo).sort();
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce primitives to objects (test in IE 9)', function(assert) {
+      assert.expect(2);
+
+      var expected = lodashStable.map(primitives, function(value) {
+        return typeof value == 'string' ? ['0'] : [];
+      });
+
+      var actual = lodashStable.map(primitives, func);
+      assert.deepEqual(actual, expected);
+
+      // IE 9 doesn't box numbers in for-in loops.
+      numberProto.a = 1;
+      assert.deepEqual(func(0), isKeys ? [] : ['a']);
+      delete numberProto.a;
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat sparse arrays as dense', function(assert) {
+      assert.expect(1);
+
+      var array = [1];
+      array[2] = 3;
+
+      var actual = func(array).sort();
+
+      assert.deepEqual(actual, ['0', '1', '2']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not coerce nullish values to objects', function(assert) {
+      assert.expect(2);
+
+      objectProto.a = 1;
+      lodashStable.each([null, undefined], function(value) {
+        assert.deepEqual(func(value), []);
+      });
+      delete objectProto.a;
+    });
+
+    QUnit.test('`_.' + methodName + '` should return keys for custom properties on arrays', function(assert) {
+      assert.expect(1);
+
+      var array = [1];
+      array.a = 1;
+
+      var actual = func(array).sort();
+
+      assert.deepEqual(actual, ['0', 'a']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of arrays', function(assert) {
+      assert.expect(1);
+
+      arrayProto.a = 1;
+
+      var expected = isKeys ? ['0'] : ['0', 'a'],
+          actual = func([1]).sort();
+
+      assert.deepEqual(actual, expected);
+
+      delete arrayProto.a;
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      var values = [args, strictArgs],
+          expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2']));
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(value).sort();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return keys for custom properties on `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      var values = [args, strictArgs],
+          expected = lodashStable.map(values, lodashStable.constant(['0', '1', '2', 'a']));
+
+      var actual = lodashStable.map(values, function(value) {
+        value.a = 1;
+        var result = func(value).sort();
+        delete value.a;
+        return result;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      var values = [args, strictArgs],
+          expected = lodashStable.map(values, lodashStable.constant(isKeys ? ['0', '1', '2'] : ['0', '1', '2', 'a']));
+
+      var actual = lodashStable.map(values, function(value) {
+        objectProto.a = 1;
+        var result = func(value).sort();
+        delete objectProto.a;
+        return result;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with string objects', function(assert) {
+      assert.expect(1);
+
+      var actual = func(Object('abc')).sort();
+
+      assert.deepEqual(actual, ['0', '1', '2']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return keys for custom properties on string objects', function(assert) {
+      assert.expect(1);
+
+      var object = Object('a');
+      object.a = 1;
+
+      var actual = func(object).sort();
+
+      assert.deepEqual(actual, ['0', 'a']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited string keyed properties of string objects', function(assert) {
+      assert.expect(1);
+
+      stringProto.a = 1;
+
+      var expected = isKeys ? ['0'] : ['0', 'a'],
+          actual = func(Object('a')).sort();
+
+      assert.deepEqual(actual, expected);
+
+      delete stringProto.a;
+    });
+
+    QUnit.test('`_.' + methodName + '` skips the `constructor` property on prototype objects', function(assert) {
+      assert.expect(3);
+
+      function Foo() {}
+      Foo.prototype.a = 1;
+
+      var expected = ['a'];
+      assert.deepEqual(func(Foo.prototype), expected);
+
+      Foo.prototype = { 'constructor': Foo, 'a': 1 };
+      assert.deepEqual(func(Foo.prototype), expected);
+
+      var Fake = { 'prototype': {} };
+      Fake.prototype.constructor = Fake;
+      assert.deepEqual(func(Fake.prototype), ['constructor']);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.last');
+
+  (function() {
+    var array = [1, 2, 3, 4];
+
+    QUnit.test('should return the last element', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.last(array), 4);
+    });
+
+    QUnit.test('should return `undefined` when querying empty arrays', function(assert) {
+      assert.expect(1);
+
+      var array = [];
+      array['-1'] = 1;
+
+      assert.strictEqual(_.last([]), undefined);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.last);
+
+      assert.deepEqual(actual, [3, 6, 9]);
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_(array).last(), 4);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(array).chain().last() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should not execute immediately when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _(array).chain().last();
+        assert.strictEqual(wrapped.__wrapped__, array);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var largeArray = lodashStable.range(LARGE_ARRAY_SIZE),
+            smallArray = array;
+
+        lodashStable.times(2, function(index) {
+          var array = index ? largeArray : smallArray,
+              wrapped = _(array).filter(isEven);
+
+          assert.strictEqual(wrapped.last(), _.last(_.filter(array, isEven)));
+        });
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.lowerCase');
+
+  (function() {
+    QUnit.test('should lowercase as space-separated words', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.lowerCase('--Foo-Bar--'), 'foo bar');
+      assert.strictEqual(_.lowerCase('fooBar'), 'foo bar');
+      assert.strictEqual(_.lowerCase('__FOO_BAR__'), 'foo bar');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.lowerFirst');
+
+  (function() {
+    QUnit.test('should lowercase only the first character', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.lowerFirst('fred'), 'fred');
+      assert.strictEqual(_.lowerFirst('Fred'), 'fred');
+      assert.strictEqual(_.lowerFirst('FRED'), 'fRED');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.lt');
+
+  (function() {
+    QUnit.test('should return `true` if `value` is less than `other`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.lt(1, 3), true);
+      assert.strictEqual(_.lt('abc', 'def'), true);
+    });
+
+    QUnit.test('should return `false` if `value` >= `other`', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.lt(3, 1), false);
+      assert.strictEqual(_.lt(3, 3), false);
+      assert.strictEqual(_.lt('def', 'abc'), false);
+      assert.strictEqual(_.lt('def', 'def'), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.lte');
+
+  (function() {
+    QUnit.test('should return `true` if `value` is <= `other`', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.lte(1, 3), true);
+      assert.strictEqual(_.lte(3, 3), true);
+      assert.strictEqual(_.lte('abc', 'def'), true);
+      assert.strictEqual(_.lte('def', 'def'), true);
+    });
+
+    QUnit.test('should return `false` if `value` > `other`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.lt(3, 1), false);
+      assert.strictEqual(_.lt('def', 'abc'), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.lastIndexOf');
+
+  (function() {
+    var array = [1, 2, 3, 1, 2, 3];
+
+    QUnit.test('should return the index of the last matched value', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.lastIndexOf(array, 3), 5);
+    });
+
+    QUnit.test('should work with a positive `fromIndex`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.lastIndexOf(array, 1, 2), 0);
+    });
+
+    QUnit.test('should work with `fromIndex` >= `array.length`', function(assert) {
+      assert.expect(1);
+
+      var values = [6, 8, Math.pow(2, 32), Infinity],
+          expected = lodashStable.map(values, lodashStable.constant([-1, 3, -1]));
+
+      var actual = lodashStable.map(values, function(fromIndex) {
+        return [
+          _.lastIndexOf(array, undefined, fromIndex),
+          _.lastIndexOf(array, 1, fromIndex),
+          _.lastIndexOf(array, '', fromIndex)
+        ];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with a negative `fromIndex`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.lastIndexOf(array, 2, -3), 1);
+    });
+
+    QUnit.test('should work with a negative `fromIndex` <= `-array.length`', function(assert) {
+      assert.expect(1);
+
+      var values = [-6, -8, -Infinity],
+          expected = lodashStable.map(values, alwaysZero);
+
+      var actual = lodashStable.map(values, function(fromIndex) {
+        return _.lastIndexOf(array, 1, fromIndex);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat falsey `fromIndex` values correctly', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? 5 : -1;
+      });
+
+      var actual = lodashStable.map(falsey, function(fromIndex) {
+        return _.lastIndexOf(array, 3, fromIndex);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce `fromIndex` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.lastIndexOf(array, 2, 4.2), 4);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('indexOf methods');
+
+  lodashStable.each(['indexOf', 'lastIndexOf', 'sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
+    var func = _[methodName],
+        isIndexOf = !/last/i.test(methodName),
+        isSorted = /^sorted/.test(methodName);
+
+    QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, lodashStable.constant(-1));
+
+      var actual = lodashStable.map(falsey, function(array, index) {
+        try {
+          return index ? func(array) : func();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `-1` for an unmatched value', function(assert) {
+      assert.expect(5);
+
+      var array = [1, 2, 3],
+          empty = [];
+
+      assert.strictEqual(func(array, 4), -1);
+      assert.strictEqual(func(array, 4, true), -1);
+      assert.strictEqual(func(array, undefined, true), -1);
+
+      assert.strictEqual(func(empty, undefined), -1);
+      assert.strictEqual(func(empty, undefined, true), -1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not match values on empty arrays', function(assert) {
+      assert.expect(2);
+
+      var array = [];
+      array[-1] = 0;
+
+      assert.strictEqual(func(array, undefined), -1);
+      assert.strictEqual(func(array, 0, true), -1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
+      assert.expect(3);
+
+      var array = isSorted
+        ? [1, 2, NaN, NaN]
+        : [1, NaN, 3, NaN, 5, NaN];
+
+      if (isSorted) {
+        assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3);
+        skipAssert(assert, 2);
+      }
+      else {
+        assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5);
+        assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1);
+        assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should match `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(func([-0], 0), 0);
+      assert.strictEqual(func([0], -0), 0);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.map');
+
+  (function() {
+    var array = [1, 2];
+
+    QUnit.test('should map values in `collection` to a new array', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1, 'b': 2 },
+          expected = ['1', '2'];
+
+      assert.deepEqual(_.map(array, String), expected);
+      assert.deepEqual(_.map(object, String), expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': 'x' }, { 'a': 'y' }];
+      assert.deepEqual(_.map(objects, 'a'), ['x', 'y']);
+    });
+
+    QUnit.test('should iterate over own string keyed properties of objects', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var actual = _.map(new Foo, identity);
+      assert.deepEqual(actual, [1]);
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1, 'b': 2 },
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([1, 2]));
+
+      lodashStable.each([array, object], function(collection) {
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? _.map(collection, value) : _.map(collection);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should accept a falsey `collection` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyArray);
+
+      var actual = lodashStable.map(falsey, function(collection, index) {
+        try {
+          return index ? _.map(collection) : _.map();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat number values for `collection` as empty', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.map(1), []);
+    });
+
+    QUnit.test('should treat a nodelist as an array-like object', function(assert) {
+      assert.expect(1);
+
+      if (document) {
+        var actual = _.map(document.getElementsByTagName('body'), function(element) {
+          return element.nodeName.toLowerCase();
+        });
+
+        assert.deepEqual(actual, ['body']);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work with objects with non-number length properties', function(assert) {
+      assert.expect(1);
+
+      var value = { 'value': 'x' },
+          object = { 'length': { 'value': 'x' } };
+
+      assert.deepEqual(_.map(object, identity), [value]);
+    });
+
+    QUnit.test('should return a wrapped value when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(array).map(noop) instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var args,
+            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            expected = [1, 0, _.map(array.slice(1), square)];
+
+        _(array).slice(1).map(function(value, index, array) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, [1, 0, array.slice(1)]);
+
+        args = undefined;
+        _(array).slice(1).map(square).map(function(value, index, array) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        args = undefined;
+        _(array).slice(1).map(square).map(function(value, index) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        args = undefined;
+        _(array).slice(1).map(square).map(function(value) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, [1]);
+
+        args = undefined;
+        _(array).slice(1).map(square).map(function() {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, expected);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.mapKeys');
+
+  (function() {
+    var array = [1, 2],
+        object = { 'a': 1, 'b': 2 };
+
+    QUnit.test('should map keys in `object` to a new object', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mapKeys(object, String);
+      assert.deepEqual(actual, { '1': 1, '2': 2 });
+    });
+
+    QUnit.test('should treat arrays like objects', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mapKeys(array, String);
+      assert.deepEqual(actual, { '1': 1, '2': 2 });
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mapKeys({ 'a': { 'b': 'c' } }, 'b');
+      assert.deepEqual(actual, { 'c': { 'b': 'c' } });
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2 },
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant({ '1': 1, '2': 2 }));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.mapKeys(object, value) : _.mapKeys(object);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.mapValues');
+
+  (function() {
+    var array = [1, 2],
+        object = { 'a': 1, 'b': 2 };
+
+    QUnit.test('should map values in `object` to a new object', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mapValues(object, String);
+      assert.deepEqual(actual, { 'a': '1', 'b': '2' });
+    });
+
+    QUnit.test('should treat arrays like objects', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mapValues(array, String);
+      assert.deepEqual(actual, { '0': '1', '1': '2' });
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mapValues({ 'a': { 'b': 1 } }, 'b');
+      assert.deepEqual(actual, { 'a': 1 });
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2 },
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([true, false]));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var result = index ? _.mapValues(object, value) : _.mapValues(object);
+        return [lodashStable.isEqual(result, object), result === object];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.mapKeys and lodash.mapValues');
+
+  lodashStable.each(['mapKeys', 'mapValues'], function(methodName) {
+    var func = _[methodName],
+        object = { 'a': 1, 'b': 2 };
+
+    QUnit.test('`_.' + methodName + '` should iterate over own string keyed properties of objects', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 'a';
+      }
+      Foo.prototype.b = 'b';
+
+      var actual = func(new Foo, function(value, key) { return key; });
+      assert.deepEqual(actual, { 'a': 'a' });
+    });
+
+    QUnit.test('`_.' + methodName + '` should accept a falsey `object` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyObject);
+
+      var actual = lodashStable.map(falsey, function(object, index) {
+        try {
+          return index ? func(object) : func();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(object)[methodName](noop) instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.matches');
+
+  (function() {
+    QUnit.test('should create a function that performs a deep comparison between `source` and a given object', function(assert) {
+      assert.expect(6);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          matches = _.matches({ 'a': 1 });
+
+      assert.strictEqual(matches.length, 1);
+      assert.strictEqual(matches(object), true);
+
+      matches = _.matches({ 'b': 1 });
+      assert.strictEqual(matches(object), false);
+
+      matches = _.matches({ 'a': 1, 'c': 3 });
+      assert.strictEqual(matches(object), true);
+
+      matches = _.matches({ 'c': 3, 'd': 4 });
+      assert.strictEqual(matches(object), false);
+
+      object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
+      matches = _.matches({ 'a': { 'b': { 'c': 1 } } });
+
+      assert.strictEqual(matches(object), true);
+    });
+
+    QUnit.test('should match inherited string keyed `object` properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var object = { 'a': new Foo },
+          matches = _.matches({ 'a': { 'b': 2 } });
+
+      assert.strictEqual(matches(object), true);
+    });
+
+    QUnit.test('should not match by inherited `source` properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 2 }],
+          source = new Foo,
+          actual = lodashStable.map(objects, _.matches(source)),
+          expected = lodashStable.map(objects, alwaysTrue);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should compare a variety of `source` property values', function(assert) {
+      assert.expect(2);
+
+      var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
+          object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
+          matches = _.matches(object1);
+
+      assert.strictEqual(matches(object1), true);
+      assert.strictEqual(matches(object2), false);
+    });
+
+    QUnit.test('should match `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      var object1 = { 'a': -0 },
+          object2 = { 'a': 0 },
+          matches = _.matches(object1);
+
+      assert.strictEqual(matches(object2), true);
+
+      matches = _.matches(object2);
+      assert.strictEqual(matches(object1), true);
+    });
+
+    QUnit.test('should compare functions by reference', function(assert) {
+      assert.expect(3);
+
+      var object1 = { 'a': lodashStable.noop },
+          object2 = { 'a': noop },
+          object3 = { 'a': {} },
+          matches = _.matches(object1);
+
+      assert.strictEqual(matches(object1), true);
+      assert.strictEqual(matches(object2), false);
+      assert.strictEqual(matches(object3), false);
+    });
+
+    QUnit.test('should work with a function for `object`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.a = { 'b': 1, 'c': 2 };
+
+      var matches = _.matches({ 'a': { 'b': 1 } });
+      assert.strictEqual(matches(Foo), true);
+    });
+
+    QUnit.test('should work with a function for `source`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.a = 1;
+      Foo.b = function() {};
+      Foo.c = 3;
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': Foo.b, 'c': 3 }],
+          actual = lodashStable.map(objects, _.matches(Foo));
+
+      assert.deepEqual(actual, [false, true]);
+    });
+
+    QUnit.test('should work with a non-plain `object`', function(assert) {
+      assert.expect(1);
+
+      function Foo(object) { lodashStable.assign(this, object); }
+
+      var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
+          matches = _.matches({ 'a': { 'b': 1 } });
+
+      assert.strictEqual(matches(object), true);
+    });
+
+    QUnit.test('should partial match arrays', function(assert) {
+      assert.expect(3);
+
+      var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
+          actual = lodashStable.filter(objects, _.matches({ 'a': ['d'] }));
+
+      assert.deepEqual(actual, [objects[1]]);
+
+      actual = lodashStable.filter(objects, _.matches({ 'a': ['b', 'd'] }));
+      assert.deepEqual(actual, []);
+
+      actual = lodashStable.filter(objects, _.matches({ 'a': ['d', 'b'] }));
+      assert.deepEqual(actual, []);
+    });
+
+    QUnit.test('should partial match arrays of objects', function(assert) {
+      assert.expect(1);
+
+      var objects = [
+        { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 5, 'd': 6 }] },
+        { 'a': [{ 'b': 1, 'c': 2 }, { 'b': 4, 'c': 6, 'd': 7 }] }
+      ];
+
+      var actual = lodashStable.filter(objects, _.matches({ 'a': [{ 'b': 1 }, { 'b': 4, 'c': 5 }] }));
+      assert.deepEqual(actual, [objects[0]]);
+    });
+
+    QUnit.test('should partial match maps', function(assert) {
+      assert.expect(3);
+
+      if (Map) {
+        var objects = [{ 'a': new Map }, { 'a': new Map }];
+        objects[0].a.set('a', 1);
+        objects[1].a.set('a', 1);
+        objects[1].a.set('b', 2);
+
+        var map = new Map;
+        map.set('b', 2);
+        var actual = lodashStable.filter(objects, _.matches({ 'a': map }));
+
+        assert.deepEqual(actual, [objects[1]]);
+
+        map['delete']('b');
+        actual = lodashStable.filter(objects, _.matches({ 'a': map }));
+
+        assert.deepEqual(actual, objects);
+
+        map.set('c', 3);
+        actual = lodashStable.filter(objects, _.matches({ 'a': map }));
+
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should partial match sets', function(assert) {
+      assert.expect(3);
+
+      if (Set) {
+        var objects = [{ 'a': new Set }, { 'a': new Set }];
+        objects[0].a.add(1);
+        objects[1].a.add(1);
+        objects[1].a.add(2);
+
+        var set = new Set;
+        set.add(2);
+        var actual = lodashStable.filter(objects, _.matches({ 'a': set }));
+
+        assert.deepEqual(actual, [objects[1]]);
+
+        set['delete'](2);
+        actual = lodashStable.filter(objects, _.matches({ 'a': set }));
+
+        assert.deepEqual(actual, objects);
+
+        set.add(3);
+        actual = lodashStable.filter(objects, _.matches({ 'a': set }));
+
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should match `undefined` values', function(assert) {
+      assert.expect(3);
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
+          actual = lodashStable.map(objects, _.matches({ 'b': undefined })),
+          expected = [false, false, true];
+
+      assert.deepEqual(actual, expected);
+
+      actual = lodashStable.map(objects, _.matches({ 'a': 1, 'b': undefined }));
+
+      assert.deepEqual(actual, expected);
+
+      objects = [{ 'a': { 'b': 1 } }, { 'a': { 'b': 1, 'c': 1 } }, { 'a': { 'b': 1, 'c': undefined } }];
+      actual = lodashStable.map(objects, _.matches({ 'a': { 'c': undefined } }));
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should match `undefined` values on primitives', function(assert) {
+      assert.expect(3);
+
+      numberProto.a = 1;
+      numberProto.b = undefined;
+
+      try {
+        var matches = _.matches({ 'b': undefined });
+        assert.strictEqual(matches(1), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      try {
+        matches = _.matches({ 'a': 1, 'b': undefined });
+        assert.strictEqual(matches(1), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      numberProto.a = { 'b': 1, 'c': undefined };
+      try {
+        matches = _.matches({ 'a': { 'c': undefined } });
+        assert.strictEqual(matches(1), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      delete numberProto.a;
+      delete numberProto.b;
+    });
+
+    QUnit.test('should return `false` when `object` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse),
+          matches = _.matches({ 'a': 1 });
+
+      var actual = lodashStable.map(values, function(value, index) {
+        try {
+          return index ? matches(value) : matches();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing an empty `source` to a nullish `object`', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysTrue),
+          matches = _.matches({});
+
+      var actual = lodashStable.map(values, function(value, index) {
+        try {
+          return index ? matches(value) : matches();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing an empty `source`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1 },
+          expected = lodashStable.map(empties, alwaysTrue);
+
+      var actual = lodashStable.map(empties, function(value) {
+        var matches = _.matches(value);
+        return matches(object);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` when comparing a `source` of empty arrays and objects', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
+          actual = lodashStable.filter(objects, _.matches({ 'a': [], 'b': {} }));
+
+      assert.deepEqual(actual, objects);
+    });
+
+    QUnit.test('should not change behavior if `source` is modified', function(assert) {
+      assert.expect(9);
+
+      var sources = [
+        { 'a': { 'b': 2, 'c': 3 } },
+        { 'a': 1, 'b': 2 },
+        { 'a': 1 }
+      ];
+
+      lodashStable.each(sources, function(source, index) {
+        var object = lodashStable.cloneDeep(source),
+            matches = _.matches(source);
+
+        assert.strictEqual(matches(object), true);
+
+        if (index) {
+          source.a = 2;
+          source.b = 1;
+          source.c = 3;
+        } else {
+          source.a.b = 1;
+          source.a.c = 2;
+          source.a.d = 3;
+        }
+        assert.strictEqual(matches(object), true);
+        assert.strictEqual(matches(source), false);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.matchesProperty');
+
+  (function() {
+    QUnit.test('should create a function that performs a deep comparison between a property value and `srcValue`', function(assert) {
+      assert.expect(6);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          matches = _.matchesProperty('a', 1);
+
+      assert.strictEqual(matches.length, 1);
+      assert.strictEqual(matches(object), true);
+
+      matches = _.matchesProperty('b', 3);
+      assert.strictEqual(matches(object), false);
+
+      matches = _.matchesProperty('a', { 'a': 1, 'c': 3 });
+      assert.strictEqual(matches({ 'a': object }), true);
+
+      matches = _.matchesProperty('a', { 'c': 3, 'd': 4 });
+      assert.strictEqual(matches(object), false);
+
+      object = { 'a': { 'b': { 'c': 1, 'd': 2 }, 'e': 3 }, 'f': 4 };
+      matches = _.matchesProperty('a', { 'b': { 'c': 1 } });
+
+      assert.strictEqual(matches(object), true);
+    });
+
+    QUnit.test('should support deep paths', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var matches = _.matchesProperty(path, 2);
+        assert.strictEqual(matches(object), true);
+      });
+    });
+
+    QUnit.test('should work with a non-string `path`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3];
+
+      lodashStable.each([1, [1]], function(path) {
+        var matches = _.matchesProperty(path, 2);
+        assert.strictEqual(matches(array), true);
+      });
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object1 = { '-0': 'a' },
+          object2 = { '0': 'b' },
+          pairs = [[object1, object2], [object1, object2], [object2, object1], [object2, object1]],
+          props = [-0, Object(-0), 0, Object(0)],
+          values = ['a', 'a', 'b', 'b'],
+          expected = lodashStable.map(props, lodashStable.constant([true, false]));
+
+      var actual = lodashStable.map(props, function(key, index) {
+        var matches = _.matchesProperty(key, values[index]),
+            pair = pairs[index];
+
+        return [matches(pair[0]), matches(pair[1])];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce key to a string', function(assert) {
+      assert.expect(1);
+
+      function fn() {}
+      fn.toString = lodashStable.constant('fn');
+
+      var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
+          values = [null, undefined, fn, {}];
+
+      var expected = lodashStable.transform(values, function(result) {
+        result.push(true, true);
+      });
+
+      var actual = lodashStable.transform(objects, function(result, object, index) {
+        var key = values[index];
+        lodashStable.each([key, [key]], function(path) {
+          var matches = _.matchesProperty(path, object[key]);
+          result.push(matches(object));
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should match a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': 1, 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        var matches = _.matchesProperty(path, 1);
+        assert.strictEqual(matches(object), true);
+      });
+    });
+
+    QUnit.test('should return `false` if parts of `path` are missing', function(assert) {
+      assert.expect(4);
+
+      var object = {};
+
+      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
+        var matches = _.matchesProperty(path, 1);
+        assert.strictEqual(matches(object), false);
+      });
+    });
+
+    QUnit.test('should return `false` for deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
+        var matches = _.matchesProperty(path, 1);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          try {
+            return index ? matches(value) : matches();
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should match inherited string keyed `srcValue` properties', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.b = 2;
+
+      var object = { 'a': new Foo };
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var matches = _.matchesProperty(path, { 'b': 2 });
+        assert.strictEqual(matches(object), true);
+      });
+    });
+
+    QUnit.test('should not match by inherited `srcValue` properties', function(assert) {
+      assert.expect(2);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 2 } }],
+          expected = lodashStable.map(objects, alwaysTrue);
+
+      lodashStable.each(['a', ['a']], function(path) {
+        assert.deepEqual(lodashStable.map(objects, _.matchesProperty(path, new Foo)), expected);
+      });
+    });
+
+    QUnit.test('should compare a variety of values', function(assert) {
+      assert.expect(2);
+
+      var object1 = { 'a': false, 'b': true, 'c': '3', 'd': 4, 'e': [5], 'f': { 'g': 6 } },
+          object2 = { 'a': 0, 'b': 1, 'c': 3, 'd': '4', 'e': ['5'], 'f': { 'g': '6' } },
+          matches = _.matchesProperty('a', object1);
+
+      assert.strictEqual(matches({ 'a': object1 }), true);
+      assert.strictEqual(matches({ 'a': object2 }), false);
+    });
+
+    QUnit.test('should match `-0` as `0`', function(assert) {
+      assert.expect(2);
+
+      var matches = _.matchesProperty('a', -0);
+      assert.strictEqual(matches({ 'a': 0 }), true);
+
+      matches = _.matchesProperty('a', 0);
+      assert.strictEqual(matches({ 'a': -0 }), true);
+    });
+
+    QUnit.test('should compare functions by reference', function(assert) {
+      assert.expect(3);
+
+      var object1 = { 'a': lodashStable.noop },
+          object2 = { 'a': noop },
+          object3 = { 'a': {} },
+          matches = _.matchesProperty('a', object1);
+
+      assert.strictEqual(matches({ 'a': object1 }), true);
+      assert.strictEqual(matches({ 'a': object2 }), false);
+      assert.strictEqual(matches({ 'a': object3 }), false);
+    });
+
+    QUnit.test('should work with a function for `srcValue`', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.a = 1;
+      Foo.b = function() {};
+      Foo.c = 3;
+
+      var objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': Foo.b, 'c': 3 } }],
+          actual = lodashStable.map(objects, _.matchesProperty('a', Foo));
+
+      assert.deepEqual(actual, [false, true]);
+    });
+
+    QUnit.test('should work with a non-plain `srcValue`', function(assert) {
+      assert.expect(1);
+
+      function Foo(object) { lodashStable.assign(this, object); }
+
+      var object = new Foo({ 'a': new Foo({ 'b': 1, 'c': 2 }) }),
+          matches = _.matchesProperty('a', { 'b': 1 });
+
+      assert.strictEqual(matches(object), true);
+    });
+
+    QUnit.test('should partial match arrays', function(assert) {
+      assert.expect(3);
+
+      var objects = [{ 'a': ['b'] }, { 'a': ['c', 'd'] }],
+          actual = lodashStable.filter(objects, _.matchesProperty('a', ['d']));
+
+      assert.deepEqual(actual, [objects[1]]);
+
+      actual = lodashStable.filter(objects, _.matchesProperty('a', ['b', 'd']));
+      assert.deepEqual(actual, []);
+
+      actual = lodashStable.filter(objects, _.matchesProperty('a', ['d', 'b']));
+      assert.deepEqual(actual, []);
+    });
+
+    QUnit.test('should partial match arrays of objects', function(assert) {
+      assert.expect(1);
+
+      var objects = [
+        { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 5, 'c': 6 }] },
+        { 'a': [{ 'a': 1, 'b': 2 }, { 'a': 4, 'b': 6, 'c': 7 }] }
+      ];
+
+      var actual = lodashStable.filter(objects, _.matchesProperty('a', [{ 'a': 1 }, { 'a': 4, 'b': 5 }]));
+      assert.deepEqual(actual, [objects[0]]);
+    });
+    QUnit.test('should partial match maps', function(assert) {
+      assert.expect(3);
+
+      if (Map) {
+        var objects = [{ 'a': new Map }, { 'a': new Map }];
+        objects[0].a.set('a', 1);
+        objects[1].a.set('a', 1);
+        objects[1].a.set('b', 2);
+
+        var map = new Map;
+        map.set('b', 2);
+        var actual = lodashStable.filter(objects, _.matchesProperty('a', map));
+
+        assert.deepEqual(actual, [objects[1]]);
+
+        map['delete']('b');
+        actual = lodashStable.filter(objects, _.matchesProperty('a', map));
+
+        assert.deepEqual(actual, objects);
+
+        map.set('c', 3);
+        actual = lodashStable.filter(objects, _.matchesProperty('a', map));
+
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should partial match sets', function(assert) {
+      assert.expect(3);
+
+      if (Set) {
+        var objects = [{ 'a': new Set }, { 'a': new Set }];
+        objects[0].a.add(1);
+        objects[1].a.add(1);
+        objects[1].a.add(2);
+
+        var set = new Set;
+        set.add(2);
+        var actual = lodashStable.filter(objects, _.matchesProperty('a', set));
+
+        assert.deepEqual(actual, [objects[1]]);
+
+        set['delete'](2);
+        actual = lodashStable.filter(objects, _.matchesProperty('a', set));
+
+        assert.deepEqual(actual, objects);
+
+        set.add(3);
+        actual = lodashStable.filter(objects, _.matchesProperty('a', set));
+
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should match `undefined` values', function(assert) {
+      assert.expect(2);
+
+      var objects = [{ 'a': 1 }, { 'a': 1, 'b': 1 }, { 'a': 1, 'b': undefined }],
+          actual = lodashStable.map(objects, _.matchesProperty('b', undefined)),
+          expected = [false, false, true];
+
+      assert.deepEqual(actual, expected);
+
+      objects = [{ 'a': { 'a': 1 } }, { 'a': { 'a': 1, 'b': 1 } }, { 'a': { 'a': 1, 'b': undefined } }];
+      actual = lodashStable.map(objects, _.matchesProperty('a', { 'b': undefined }));
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should match `undefined` values of nested objects', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': { 'b': undefined } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var matches = _.matchesProperty(path, undefined);
+        assert.strictEqual(matches(object), true);
+      });
+
+      lodashStable.each(['a.a', ['a', 'a']], function(path) {
+        var matches = _.matchesProperty(path, undefined);
+        assert.strictEqual(matches(object), false);
+      });
+    });
+
+    QUnit.test('should match `undefined` values on primitives', function(assert) {
+      assert.expect(2);
+
+      numberProto.a = 1;
+      numberProto.b = undefined;
+
+      try {
+        var matches = _.matchesProperty('b', undefined);
+        assert.strictEqual(matches(1), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      numberProto.a = { 'b': 1, 'c': undefined };
+      try {
+        matches = _.matchesProperty('a', { 'c': undefined });
+        assert.strictEqual(matches(1), true);
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+      delete numberProto.a;
+      delete numberProto.b;
+    });
+
+    QUnit.test('should return `false` when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        var matches = _.matchesProperty(path, 1);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          try {
+            return index ? matches(value) : matches();
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `true` when comparing a `srcValue` of empty arrays and objects', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': [1], 'b': { 'c': 1 } }, { 'a': [2, 3], 'b': { 'd': 2 } }],
+          matches = _.matchesProperty('a', { 'a': [], 'b': {} });
+
+      var actual = lodashStable.filter(objects, function(object) {
+        return matches({ 'a': object });
+      });
+
+      assert.deepEqual(actual, objects);
+    });
+
+    QUnit.test('should not change behavior if `srcValue` is modified', function(assert) {
+      assert.expect(9);
+
+      lodashStable.each([{ 'a': { 'b': 2, 'c': 3 } }, { 'a': 1, 'b': 2 }, { 'a': 1 }], function(source, index) {
+        var object = lodashStable.cloneDeep(source),
+            matches = _.matchesProperty('a', source);
+
+        assert.strictEqual(matches({ 'a': object }), true);
+
+        if (index) {
+          source.a = 2;
+          source.b = 1;
+          source.c = 3;
+        } else {
+          source.a.b = 1;
+          source.a.c = 2;
+          source.a.d = 3;
+        }
+        assert.strictEqual(matches({ 'a': object }), true);
+        assert.strictEqual(matches({ 'a': source }), false);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.max');
+
+  (function() {
+    QUnit.test('should return the largest value from a collection', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.max([1, 2, 3]), 3);
+    });
+
+    QUnit.test('should return `undefined` for empty collections', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat([[]]),
+          expected = lodashStable.map(values, noop);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        try {
+          return index ? _.max(value) : _.max();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with non-numeric collection values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.max(['a', 'b']), 'b');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.mean');
+
+  (function() {
+    QUnit.test('should return the mean of an array of numbers', function(assert) {
+      assert.expect(1);
+
+      var array = [4, 2, 8, 6];
+      assert.strictEqual(_.mean(array), 5);
+    });
+
+    QUnit.test('should return `NaN` when passing empty `array` values', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, alwaysNaN),
+          actual = lodashStable.map(empties, _.mean);
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.meanBy');
+
+  (function() {
+    var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
+
+    QUnit.test('should work with an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var actual = _.meanBy(objects, function(object) {
+        return object.a;
+      });
+
+      assert.deepEqual(actual, 2);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.meanBy(objects, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [{ 'a': 2 }]);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var arrays = [[2], [3], [1]];
+      assert.strictEqual(_.meanBy(arrays, 0), 2);
+      assert.strictEqual(_.meanBy(objects, 'a'), 2);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.memoize');
+
+  (function() {
+    QUnit.test('should memoize results based on the first argument given', function(assert) {
+      assert.expect(2);
+
+      var memoized = _.memoize(function(a, b, c) {
+        return a + b + c;
+      });
+
+      assert.strictEqual(memoized(1, 2, 3), 6);
+      assert.strictEqual(memoized(1, 3, 5), 6);
+    });
+
+    QUnit.test('should support a `resolver` argument', function(assert) {
+      assert.expect(2);
+
+      var fn = function(a, b, c) { return a + b + c; },
+          memoized = _.memoize(fn, fn);
+
+      assert.strictEqual(memoized(1, 2, 3), 6);
+      assert.strictEqual(memoized(1, 3, 5), 9);
+    });
+
+    QUnit.test('should use `this` binding of function for `resolver`', function(assert) {
+      assert.expect(2);
+
+      var fn = function(a, b, c) { return a + this.b + this.c; },
+          memoized = _.memoize(fn, fn);
+
+      var object = { 'memoized': memoized, 'b': 2, 'c': 3 };
+      assert.strictEqual(object.memoized(1), 6);
+
+      object.b = 3;
+      object.c = 5;
+      assert.strictEqual(object.memoized(1), 9);
+    });
+
+    QUnit.test('should throw a TypeError if `resolve` is truthy and not a function', function(assert) {
+      assert.expect(1);
+
+      assert.raises(function() { _.memoize(noop, true); }, TypeError);
+    });
+
+    QUnit.test('should not error if `resolver` is falsey', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysTrue);
+
+      var actual = lodashStable.map(falsey, function(resolver, index) {
+        try {
+          return _.isFunction(index ? _.memoize(noop, resolver) : _.memoize(noop));
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should check cache for own properties', function(assert) {
+      assert.expect(1);
+
+      var props = [
+        'constructor',
+        'hasOwnProperty',
+        'isPrototypeOf',
+        'propertyIsEnumerable',
+        'toLocaleString',
+        'toString',
+        'valueOf'
+      ];
+
+      var memoized = _.memoize(identity);
+
+      var actual = lodashStable.map(props, function(value) {
+        return memoized(value);
+      });
+
+      assert.deepEqual(actual, props);
+    });
+
+    QUnit.test('should cache the `__proto__` key', function(assert) {
+      assert.expect(8);
+
+      var array = [],
+          key = '__proto__';
+
+      lodashStable.times(2, function(index) {
+        var count = 0,
+            resolver = index && identity;
+
+        var memoized = _.memoize(function() {
+          count++;
+          return array;
+        }, resolver);
+
+        var cache = memoized.cache;
+
+        memoized(key);
+        memoized(key);
+
+        assert.strictEqual(count, 1);
+        assert.strictEqual(cache.get(key), array);
+        assert.notOk(cache.__data__ instanceof Array);
+        assert.strictEqual(cache['delete'](key), true);
+      });
+    });
+
+    QUnit.test('should allow `_.memoize.Cache` to be customized', function(assert) {
+      assert.expect(4);
+
+      var oldCache = _.memoize.Cache;
+
+      function Cache() {
+        this.__data__ = [];
+      }
+
+      Cache.prototype = {
+        'get': function(key) {
+          var entry = _.find(this.__data__, function(entry) {
+            return key === entry.key;
+          });
+          return entry && entry.value;
+        },
+        'has': function(key) {
+          return _.some(this.__data__, function(entry) {
+            return key === entry.key;
+          });
+        },
+        'set': function(key, value) {
+          this.__data__.push({ 'key': key, 'value': value });
+          return this;
+        }
+      };
+
+      _.memoize.Cache = Cache;
+
+      var memoized = _.memoize(function(object) {
+        return 'value:' + object.id;
+      });
+
+      var cache = memoized.cache,
+          key1 = { 'id': 'a' },
+          key2 = { 'id': 'b' };
+
+      assert.strictEqual(memoized(key1), 'value:a');
+      assert.strictEqual(cache.has(key1), true);
+
+      assert.strictEqual(memoized(key2), 'value:b');
+      assert.strictEqual(cache.has(key2), true);
+
+      _.memoize.Cache = oldCache;
+    });
+
+    QUnit.test('should works with an immutable `_.memoize.Cache` ', function(assert) {
+      assert.expect(2);
+
+      var oldCache = _.memoize.Cache;
+
+      function Cache() {
+        this.__data__ = [];
+      }
+
+      Cache.prototype = {
+        'get': function(key) {
+          return _.find(this.__data__, function(entry) {
+            return key === entry.key;
+          }).value;
+        },
+        'has': function(key) {
+          return _.some(this.__data__, function(entry) {
+            return key === entry.key;
+          });
+        },
+        'set': function(key, value) {
+          var result = new Cache;
+          result.__data__ = this.__data__.concat({ 'key': key, 'value': value });
+          return result;
+        }
+      };
+
+      _.memoize.Cache = Cache;
+
+      var memoized = _.memoize(function(object) {
+        return object.id;
+      });
+
+      var key1 = { 'id': 'a' },
+          key2 = { 'id': 'b' };
+
+      memoized(key1);
+      memoized(key2);
+
+      var cache = memoized.cache;
+      assert.strictEqual(cache.has(key1), true);
+      assert.strictEqual(cache.has(key2), true);
+
+      _.memoize.Cache = oldCache;
+    });
+
+    QUnit.test('should implement a `Map` interface on the cache object', function(assert) {
+      assert.expect(164);
+
+      var keys = [null, undefined, false, true, 1, -Infinity, NaN, {}, 'a', symbol || {}];
+
+      var pairs = lodashStable.map(keys, function(key, index) {
+        var lastIndex = keys.length - 1;
+        return [key, keys[lastIndex - index]];
+      });
+
+      lodashStable.times(2, function(index) {
+        var memoize = (index ? (lodashBizarro || {}) : _).memoize,
+            Cache = memoize ? memoize.Cache : undefined,
+            cache = Cache ? new Cache(pairs) : undefined;
+
+        lodashStable.each(keys, function(key, index) {
+          if (cache) {
+            var value = pairs[index][1];
+
+            assert.deepEqual(cache.get(key), value);
+            assert.strictEqual(cache.has(key), true);
+            assert.strictEqual(cache['delete'](key), true);
+            assert.strictEqual(cache.has(key), false);
+            assert.strictEqual(cache.get(key), undefined);
+            assert.strictEqual(cache['delete'](key), false);
+            assert.strictEqual(cache.set(key, value), cache);
+            assert.strictEqual(cache.has(key), true);
+          }
+          else {
+            skipAssert(assert, 8);
+          }
+        });
+
+        if (cache) {
+          assert.strictEqual(cache.clear(), undefined);
+          assert.ok(lodashStable.every(keys, function(key) {
+            return !cache.has(key);
+          }));
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.merge');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should merge `source` into `object`', function(assert) {
+      assert.expect(1);
+
+      var names = {
+        'characters': [
+          { 'name': 'barney' },
+          { 'name': 'fred' }
+        ]
+      };
+
+      var ages = {
+        'characters': [
+          { 'age': 36 },
+          { 'age': 40 }
+        ]
+      };
+
+      var heights = {
+        'characters': [
+          { 'height': '5\'4"' },
+          { 'height': '5\'5"' }
+        ]
+      };
+
+      var expected = {
+        'characters': [
+          { 'name': 'barney', 'age': 36, 'height': '5\'4"' },
+          { 'name': 'fred', 'age': 40, 'height': '5\'5"' }
+        ]
+      };
+
+      assert.deepEqual(_.merge(names, ages, heights), expected);
+    });
+
+    QUnit.test('should merge sources containing circular references', function(assert) {
+      assert.expect(2);
+
+      var object = {
+        'foo': { 'a': 1 },
+        'bar': { 'a': 2 }
+      };
+
+      var source = {
+        'foo': { 'b': { 'c': { 'd': {} } } },
+        'bar': {}
+      };
+
+      source.foo.b.c.d = source;
+      source.bar.b = source.foo.b;
+
+      var actual = _.merge(object, source);
+
+      assert.notStrictEqual(actual.bar.b, actual.foo.b);
+      assert.strictEqual(actual.foo.b.c.d, actual.foo.b.c.d.foo.b.c.d);
+    });
+
+    QUnit.test('should work with four arguments', function(assert) {
+      assert.expect(1);
+
+      var expected = { 'a': 4 },
+          actual = _.merge({ 'a': 1 }, { 'a': 2 }, { 'a': 3 }, expected);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should merge onto function `object` values', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+
+      var source = { 'a': 1 },
+          actual = _.merge(Foo, source);
+
+      assert.strictEqual(actual, Foo);
+      assert.strictEqual(Foo.a, 1);
+    });
+
+    QUnit.test('should not merge onto nested function values', function(assert) {
+      assert.expect(3);
+
+      var source1 = { 'a': function() {} },
+          source2 = { 'a': { 'b': 1 } },
+          actual = _.merge({}, source1, source2),
+          expected = { 'a': { 'b': 1 } };
+
+      assert.deepEqual(actual, expected);
+
+      source1 = { 'a': function() {} };
+      source2 = { 'a': { 'b': 1 } };
+
+      expected = { 'a': function() {} };
+      expected.a.b = 1;
+
+      actual = _.merge(source1, source2);
+      assert.strictEqual(typeof actual.a, 'function');
+      assert.strictEqual(actual.a.b, 1);
+    });
+
+    QUnit.test('should merge onto non-plain `object` values', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+
+      var object = new Foo,
+          actual = _.merge(object, { 'a': 1 });
+
+      assert.strictEqual(actual, object);
+      assert.strictEqual(object.a, 1);
+    });
+
+    QUnit.test('should treat sparse array sources as dense', function(assert) {
+      assert.expect(2);
+
+      var array = [1];
+      array[2] = 3;
+
+      var actual = _.merge([], array),
+          expected = array.slice();
+
+      expected[1] = undefined;
+
+      assert.ok('1' in actual);
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should merge `arguments` objects', function(assert) {
+      assert.expect(7);
+
+      var object1 = { 'value': args },
+          object2 = { 'value': { '3': 4 } },
+          expected = { '0': 1, '1': 2, '2': 3, '3': 4 },
+          actual = _.merge(object1, object2);
+
+      assert.notOk('3' in args);
+      assert.notOk(_.isArguments(actual.value));
+      assert.deepEqual(actual.value, expected);
+      object1.value = args;
+
+      actual = _.merge(object2, object1);
+      assert.notOk(_.isArguments(actual.value));
+      assert.deepEqual(actual.value, expected);
+
+      expected = { '0': 1, '1': 2, '2': 3 };
+
+      actual = _.merge({}, object1);
+      assert.notOk(_.isArguments(actual.value));
+      assert.deepEqual(actual.value, expected);
+    });
+
+    QUnit.test('should merge typed arrays', function(assert) {
+      assert.expect(4);
+
+      var array1 = [0],
+          array2 = [0, 0],
+          array3 = [0, 0, 0, 0],
+          array4 = [0, 0, 0, 0, 0, 0, 0, 0];
+
+      var arrays = [array2, array1, array4, array3, array2, array4, array4, array3, array2],
+          buffer = ArrayBuffer && new ArrayBuffer(8);
+
+      // Juggle for `Float64Array` shim.
+      if (root.Float64Array && (new Float64Array(buffer)).length == 8) {
+        arrays[1] = array4;
+      }
+      var expected = lodashStable.map(typedArrays, function(type, index) {
+        var array = arrays[index].slice();
+        array[0] = 1;
+        return root[type] ? { 'value': array } : false;
+      });
+
+      var actual = lodashStable.map(typedArrays, function(type) {
+        var Ctor = root[type];
+        return Ctor ? _.merge({ 'value': new Ctor(buffer) }, { 'value': [1] }) : false;
+      });
+
+      assert.ok(lodashStable.isArray(actual));
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(typedArrays, function(type, index) {
+        var array = arrays[index].slice();
+        array.push(1);
+        return root[type] ? { 'value': array } : false;
+      });
+
+      actual = lodashStable.map(typedArrays, function(type, index) {
+        var Ctor = root[type],
+            array = lodashStable.range(arrays[index].length);
+
+        array.push(1);
+        return Ctor ? _.merge({ 'value': array }, { 'value': new Ctor(buffer) }) : false;
+      });
+
+      assert.ok(lodashStable.isArray(actual));
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should assign `null` values', function(assert) {
+      assert.expect(1);
+
+      var actual = _.merge({ 'a': 1 }, { 'a': null });
+      assert.strictEqual(actual.a, null);
+    });
+
+    QUnit.test('should assign non array/typed-array/plain-object sources directly', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+
+      var values = [new Foo, new Boolean, new Date, Foo, new Number, new String, new RegExp],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        var object = _.merge({}, { 'value': value });
+        return object.value === value;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should deep clone array/typed-array/plain-object sources', function(assert) {
+      assert.expect(1);
+
+      var typedArray = Uint8Array
+        ? new Uint8Array(new ArrayBuffer(2))
+        : { 'buffer': [0, 0] };
+
+      var props = ['0', 'a', 'buffer'],
+          values = [[{ 'a': 1 }], { 'a': [1] }, typedArray],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var key = props[index],
+            object = _.merge({}, { 'value': value }),
+            newValue = object.value;
+
+        return (
+          newValue !== value &&
+          newValue[key] !== value[key] &&
+          lodashStable.isEqual(newValue, value)
+        );
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not augment source objects', function(assert) {
+      assert.expect(6);
+
+      var source1 = { 'a': [{ 'a': 1 }] },
+          source2 = { 'a': [{ 'b': 2 }] },
+          actual = _.merge({}, source1, source2);
+
+      assert.deepEqual(source1.a, [{ 'a': 1 }]);
+      assert.deepEqual(source2.a, [{ 'b': 2 }]);
+      assert.deepEqual(actual.a, [{ 'a': 1, 'b': 2 }]);
+
+      var source1 = { 'a': [[1, 2, 3]] },
+          source2 = { 'a': [[3, 4]] },
+          actual = _.merge({}, source1, source2);
+
+      assert.deepEqual(source1.a, [[1, 2, 3]]);
+      assert.deepEqual(source2.a, [[3, 4]]);
+      assert.deepEqual(actual.a, [[3, 4, 3]]);
+    });
+
+    QUnit.test('should merge plain-objects onto non plain-objects', function(assert) {
+      assert.expect(4);
+
+      function Foo(object) {
+        lodashStable.assign(this, object);
+      }
+
+      var object = { 'a': 1 },
+          actual = _.merge(new Foo, object);
+
+      assert.ok(actual instanceof Foo);
+      assert.deepEqual(actual, new Foo(object));
+
+      actual = _.merge([new Foo], [object]);
+      assert.ok(actual[0] instanceof Foo);
+      assert.deepEqual(actual, [new Foo(object)]);
+    });
+
+    QUnit.test('should not assign `undefined` values', function(assert) {
+      assert.expect(1);
+
+      var actual = _.merge({ 'a': 1 }, { 'a': undefined, 'b': undefined });
+      assert.deepEqual(actual, { 'a': 1 });
+    });
+
+    QUnit.test('should skip `undefined` values in array sources if a destination value exists', function(assert) {
+      assert.expect(2);
+
+      var array = [1];
+      array[2] = 3;
+
+      var actual = _.merge([4, 5, 6], array),
+          expected = [1, 5, 3];
+
+      assert.deepEqual(actual, expected);
+
+      array = [1, , 3];
+      array[1] = undefined;
+
+      actual = _.merge([4, 5, 6], array);
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should skip merging when `object` and `source` are the same value', function(assert) {
+      assert.expect(1);
+
+      if (defineProperty) {
+        var object = {},
+            pass = true;
+
+        defineProperty(object, 'a', {
+          'enumerable': true,
+          'configurable': true,
+          'get': function() { pass = false; },
+          'set': function() { pass = false; }
+        });
+
+        _.merge(object, object);
+        assert.ok(pass);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should convert values to arrays when merging arrays of `source`', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { '1': 'y', 'b': 'z', 'length': 2 } },
+          actual = _.merge(object, { 'a': ['x'] });
+
+      assert.deepEqual(actual, { 'a': ['x', 'y'] });
+
+      actual = _.merge({ 'a': {} }, { 'a': [] });
+      assert.deepEqual(actual, { 'a': [] });
+    });
+
+    QUnit.test('should not convert strings to arrays when merging arrays of `source`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 'abcde' },
+          actual = _.merge(object, { 'a': ['x', 'y', 'z'] });
+
+      assert.deepEqual(actual, { 'a': ['x', 'y', 'z'] });
+    });
+
+    QUnit.test('should not error on DOM elements', function(assert) {
+      assert.expect(1);
+
+      var object1 = { 'el': document && document.createElement('div') },
+          object2 = { 'el': document && document.createElement('div') },
+          pairs = [[{}, object1], [object1, object2]],
+          expected = lodashStable.map(pairs, alwaysTrue);
+
+      var actual = lodashStable.map(pairs, function(pair) {
+        try {
+          return _.merge(pair[0], pair[1]).el === pair[1].el;
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.mergeWith');
+
+  (function() {
+    QUnit.test('should handle merging if `customizer` returns `undefined`', function(assert) {
+      assert.expect(2);
+
+      var actual = _.mergeWith({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, noop);
+      assert.deepEqual(actual, { 'a': { 'b': [0, 1] } });
+
+      actual = _.mergeWith([], [undefined], identity);
+      assert.deepEqual(actual, [undefined]);
+    });
+
+    QUnit.test('should defer to `customizer` when it returns a non `undefined` value', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mergeWith({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) {
+        return lodashStable.isArray(a) ? a.concat(b) : undefined;
+      });
+
+      assert.deepEqual(actual, { 'a': { 'b': [0, 1, 2] } });
+    });
+
+    QUnit.test('should overwrite primitives with source object clones', function(assert) {
+      assert.expect(1);
+
+      var actual = _.mergeWith({ 'a': 0 }, { 'a': { 'b': ['c'] } }, function(a, b) {
+        return lodashStable.isArray(a) ? a.concat(b) : undefined;
+      });
+
+      assert.deepEqual(actual, { 'a': { 'b': ['c'] } });
+    });
+
+    QUnit.test('should clone sources when `customizer` result is `undefined`', function(assert) {
+      assert.expect(1);
+
+      var source1 = { 'a': { 'b': { 'c': 1 } } },
+          source2 = { 'a': { 'b': { 'd': 2 } } };
+
+      _.mergeWith({}, source1, source2, noop);
+      assert.deepEqual(source1.a.b, { 'c': 1 });
+    });
+
+    QUnit.test('should pop the stack of sources for each sibling property', function(assert) {
+      assert.expect(1);
+
+      var array = ['b', 'c'],
+          object = { 'a': ['a'] },
+          source = { 'a': array, 'b': array };
+
+      var actual = _.mergeWith(object, source, function(a, b) {
+        return lodashStable.isArray(a) ? a.concat(b) : undefined;
+      });
+
+      assert.deepEqual(actual, { 'a': ['a', 'b', 'c'], 'b': ['b', 'c'] });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.method');
+
+  (function() {
+    QUnit.test('should create a function that calls a method of a given object', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': alwaysOne };
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method.length, 1);
+        assert.strictEqual(method(object), 1);
+      });
+    });
+
+    QUnit.test('should work with deep property values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': alwaysTwo } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method(object), 2);
+      });
+    });
+
+    QUnit.test('should work with a non-string `path`', function(assert) {
+      assert.expect(2);
+
+      var array = lodashStable.times(3, _.constant);
+
+      lodashStable.each([1, [1]], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method(array), 1);
+      });
+    });
+
+    QUnit.test('should coerce key to a string', function(assert) {
+      assert.expect(1);
+
+      function fn() {}
+      fn.toString = lodashStable.constant('fn');
+
+      var expected = [1, 1, 2, 2, 3, 3, 4, 4],
+          objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
+          values = [null, undefined, fn, {}];
+
+      var actual = lodashStable.transform(objects, function(result, object, index) {
+        var key = values[index];
+        lodashStable.each([key, [key]], function(path) {
+          var method = _.method(key);
+          result.push(method(object));
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with inherited property values', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.a = alwaysOne;
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method(new Foo), 1);
+      });
+    });
+
+    QUnit.test('should use a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': alwaysOne, 'a': { 'b': alwaysTwo } };
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method(object), 1);
+      });
+    });
+
+    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        var method = _.method(path);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? method(value) : method();
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
+        var method = _.method(path);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? method(value) : method();
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
+      assert.expect(4);
+
+      var object = {};
+
+      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method(object), undefined);
+      });
+    });
+
+    QUnit.test('should apply partial arguments to function', function(assert) {
+      assert.expect(2);
+
+      var object = {
+        'fn': function() {
+          return slice.call(arguments);
+        }
+      };
+
+      lodashStable.each(['fn', ['fn']], function(path) {
+        var method = _.method(path, 1, 2, 3);
+        assert.deepEqual(method(object), [1, 2, 3]);
+      });
+    });
+
+    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var method = _.method(path);
+        assert.strictEqual(method(object), 1);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.methodOf');
+
+  (function() {
+    QUnit.test('should create a function that calls a method of a given key', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': alwaysOne };
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var methodOf = _.methodOf(object);
+        assert.strictEqual(methodOf.length, 1);
+        assert.strictEqual(methodOf(path), 1);
+      });
+    });
+
+    QUnit.test('should work with deep property values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': alwaysTwo } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var methodOf = _.methodOf(object);
+        assert.strictEqual(methodOf(path), 2);
+      });
+    });
+
+    QUnit.test('should work with a non-string `path`', function(assert) {
+      assert.expect(2);
+
+      var array = lodashStable.times(3, _.constant);
+
+      lodashStable.each([1, [1]], function(path) {
+        var methodOf = _.methodOf(array);
+        assert.strictEqual(methodOf(path), 1);
+      });
+    });
+
+    QUnit.test('should coerce key to a string', function(assert) {
+      assert.expect(1);
+
+      function fn() {}
+      fn.toString = lodashStable.constant('fn');
+
+      var expected = [1, 1, 2, 2, 3, 3, 4, 4],
+          objects = [{ 'null': alwaysOne }, { 'undefined': alwaysTwo }, { 'fn': alwaysThree }, { '[object Object]': alwaysFour }],
+          values = [null, undefined, fn, {}];
+
+      var actual = lodashStable.transform(objects, function(result, object, index) {
+        var key = values[index];
+        lodashStable.each([key, [key]], function(path) {
+          var methodOf = _.methodOf(object);
+          result.push(methodOf(key));
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with inherited property values', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.a = alwaysOne;
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var methodOf = _.methodOf(new Foo);
+        assert.strictEqual(methodOf(path), 1);
+      });
+    });
+
+    QUnit.test('should use a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': alwaysOne, 'a': { 'b': alwaysTwo } };
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        var methodOf = _.methodOf(object);
+        assert.strictEqual(methodOf(path), 1);
+      });
+    });
+
+    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        var actual = lodashStable.map(values, function(value, index) {
+          var methodOf = index ? _.methodOf() : _.methodOf(value);
+          return methodOf(path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
+        var actual = lodashStable.map(values, function(value, index) {
+          var methodOf = index ? _.methodOf() : _.methodOf(value);
+          return methodOf(path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
+      assert.expect(4);
+
+      var object = {},
+          methodOf = _.methodOf(object);
+
+      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
+        assert.strictEqual(methodOf(path), undefined);
+      });
+    });
+
+    QUnit.test('should apply partial arguments to function', function(assert) {
+      assert.expect(2);
+
+      var object = {
+        'fn': function() {
+          return slice.call(arguments);
+        }
+      };
+
+      var methodOf = _.methodOf(object, 1, 2, 3);
+
+      lodashStable.each(['fn', ['fn']], function(path) {
+        assert.deepEqual(methodOf(path), [1, 2, 3]);
+      });
+    });
+
+    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': function() { return this.c; }, 'c': 1 } },
+          methodOf = _.methodOf(object);
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(methodOf(path), 1);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.min');
+
+  (function() {
+    QUnit.test('should return the smallest value from a collection', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.min([1, 2, 3]), 1);
+    });
+
+    QUnit.test('should return `undefined` for empty collections', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat([[]]),
+          expected = lodashStable.map(values, noop);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        try {
+          return index ? _.min(value) : _.min();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with non-numeric collection values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.min(['a', 'b']), 'a');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('extremum methods');
+
+  lodashStable.each(['max', 'maxBy', 'min', 'minBy'], function(methodName) {
+    var func = _[methodName],
+        isMax = /^max/.test(methodName);
+
+    QUnit.test('`_.' + methodName + '` should work with Date objects', function(assert) {
+      assert.expect(1);
+
+      var curr = new Date,
+          past = new Date(0);
+
+      assert.strictEqual(func([curr, past]), isMax ? curr : past);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with extremely large arrays', function(assert) {
+      assert.expect(1);
+
+      var array = lodashStable.range(0, 5e5);
+      assert.strictEqual(func(array), isMax ? 499999 : 0);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work when chaining on an array with only one value', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = _([40])[methodName]();
+        assert.strictEqual(actual, 40);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  lodashStable.each(['maxBy', 'minBy'], function(methodName) {
+    var array = [1, 2, 3],
+        func = _[methodName],
+        isMax = methodName == 'maxBy';
+
+    QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var actual = func(array, function(n) {
+        return -n;
+      });
+
+      assert.strictEqual(actual, isMax ? 1 : 3);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }],
+          actual = func(objects, 'a');
+
+      assert.deepEqual(actual, objects[isMax ? 1 : 2]);
+
+      var arrays = [[2], [3], [1]];
+      actual = func(arrays, 0);
+
+      assert.deepEqual(actual, arrays[isMax ? 1 : 2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work when `iteratee` returns +/-Infinity', function(assert) {
+      assert.expect(1);
+
+      var value = isMax ? -Infinity : Infinity,
+          object = { 'a': value };
+
+      var actual = func([object, { 'a': value }], function(object) {
+        return object.a;
+      });
+
+      assert.strictEqual(actual, object);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.mixin');
+
+  (function() {
+    function reset(wrapper) {
+      delete wrapper.a;
+      delete wrapper.prototype.a;
+      delete wrapper.b;
+      delete wrapper.prototype.b;
+    }
+
+    function Wrapper(value) {
+      if (!(this instanceof Wrapper)) {
+        return new Wrapper(value);
+      }
+      if (_.has(value, '__wrapped__')) {
+        var actions = slice.call(value.__actions__),
+            chain = value.__chain__;
+
+        value = value.__wrapped__;
+      }
+      this.__wrapped__ = value;
+      this.__actions__ = actions || [];
+      this.__chain__ = chain || false;
+    }
+
+    Wrapper.prototype.value = function() {
+      return getUnwrappedValue(this);
+    };
+
+    var array = ['a'],
+        source = { 'a': function(array) { return array[0]; }, 'b': 'B' };
+
+    QUnit.test('should mixin `source` methods into lodash', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        _.mixin(source);
+
+        assert.strictEqual(_.a(array), 'a');
+        assert.strictEqual(_(array).a().value(), 'a');
+        assert.notOk('b' in _);
+        assert.notOk('b' in _.prototype);
+
+        reset(_);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should mixin chaining methods by reference', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        _.mixin(source);
+        _.a = alwaysB;
+
+        assert.strictEqual(_.a(array), 'b');
+        assert.strictEqual(_(array).a().value(), 'a');
+
+        reset(_);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should use a default `object` of `this`', function(assert) {
+      assert.expect(3);
+
+      var object = lodashStable.create(_);
+      object.mixin(source);
+
+      assert.strictEqual(object.a(array), 'a');
+      assert.notOk('a' in _);
+      assert.notOk('a' in _.prototype);
+
+      reset(_);
+    });
+
+    QUnit.test('should accept an `object` argument', function(assert) {
+      assert.expect(1);
+
+      var object = {};
+      _.mixin(object, source);
+      assert.strictEqual(object.a(array), 'a');
+    });
+
+    QUnit.test('should accept a function `object`', function(assert) {
+      assert.expect(2);
+
+      _.mixin(Wrapper, source);
+
+      var wrapped = Wrapper(array),
+          actual = wrapped.a();
+
+      assert.strictEqual(actual.value(), 'a');
+      assert.ok(actual instanceof Wrapper);
+
+      reset(Wrapper);
+    });
+
+    QUnit.test('should return `object`', function(assert) {
+      assert.expect(3);
+
+      var object = {};
+      assert.strictEqual(_.mixin(object, source), object);
+      assert.strictEqual(_.mixin(Wrapper, source), Wrapper);
+      assert.strictEqual(_.mixin(), _);
+
+      reset(Wrapper);
+    });
+
+    QUnit.test('should not assign inherited `source` methods', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype.a = noop;
+
+      var object = {};
+      assert.strictEqual(_.mixin(object, new Foo), object);
+    });
+
+    QUnit.test('should accept an `options` argument', function(assert) {
+      assert.expect(8);
+
+      function message(func, chain) {
+        return (func === _ ? 'lodash' : 'given') + ' function should ' + (chain ? '' : 'not ') + 'chain';
+      }
+
+      lodashStable.each([_, Wrapper], function(func) {
+        lodashStable.each([{ 'chain': false }, { 'chain': true }], function(options) {
+          if (!isNpm) {
+            if (func === _) {
+              _.mixin(source, options);
+            } else {
+              _.mixin(func, source, options);
+            }
+            var wrapped = func(array),
+                actual = wrapped.a();
+
+            if (options.chain) {
+              assert.strictEqual(actual.value(), 'a', message(func, true));
+              assert.ok(actual instanceof func, message(func, true));
+            } else {
+              assert.strictEqual(actual, 'a', message(func, false));
+              assert.notOk(actual instanceof func, message(func, false));
+            }
+            reset(func);
+          }
+          else {
+            skipAssert(assert, 2);
+          }
+        });
+      });
+    });
+
+    QUnit.test('should not extend lodash when an `object` is given with an empty `options` object', function(assert) {
+      assert.expect(1);
+
+      _.mixin({ 'a': noop }, {});
+      assert.notOk('a' in _);
+      reset(_);
+    });
+
+    QUnit.test('should not error for non-object `options` values', function(assert) {
+      assert.expect(2);
+
+      var pass = true;
+
+      try {
+        _.mixin({}, source, 1);
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass);
+
+      pass = true;
+
+      try {
+        _.mixin(source, 1);
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass);
+
+      reset(_);
+    });
+
+    QUnit.test('should not return the existing wrapped value when chaining', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([_, Wrapper], function(func) {
+        if (!isNpm) {
+          if (func === _) {
+            var wrapped = _(source),
+                actual = wrapped.mixin();
+
+            assert.strictEqual(actual.value(), _);
+          }
+          else {
+            wrapped = _(func);
+            actual = wrapped.mixin(source);
+            assert.notStrictEqual(actual, wrapped);
+          }
+          reset(func);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    QUnit.test('should produce methods that work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        _.mixin({ 'a': _.countBy, 'b': _.filter });
+
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            actual = _(array).a().map(square).b(isEven).take().value();
+
+        assert.deepEqual(actual, _.take(_.b(_.map(_.a(array), square), isEven)));
+
+        reset(_);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.multiply');
+
+  (function() {
+    QUnit.test('should multiply two numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.multiply(6, 4), 24);
+      assert.strictEqual(_.multiply(-6, 4), -24);
+      assert.strictEqual(_.multiply(-6, -4), 24);
+    });
+
+    QUnit.test('should coerce arguments to numbers', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.multiply('6', '4'), 24);
+      assert.deepEqual(_.multiply('x', 'y'), NaN);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.orderBy');
+
+  (function() {
+    var objects = [
+      { 'a': 'x', 'b': 3 },
+      { 'a': 'y', 'b': 4 },
+      { 'a': 'x', 'b': 1 },
+      { 'a': 'y', 'b': 2 }
+    ];
+
+    QUnit.test('should sort by a single property by a specified order', function(assert) {
+      assert.expect(1);
+
+      var actual = _.orderBy(objects, 'a', 'desc');
+      assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
+    });
+
+    QUnit.test('should sort by multiple properties by specified orders', function(assert) {
+      assert.expect(1);
+
+      var actual = _.orderBy(objects, ['a', 'b'], ['desc', 'asc']);
+      assert.deepEqual(actual, [objects[3], objects[1], objects[2], objects[0]]);
+    });
+
+    QUnit.test('should sort by a property in ascending order when its order is not specified', function(assert) {
+      assert.expect(2);
+
+      var expected = [objects[2], objects[0], objects[3], objects[1]],
+          actual = _.orderBy(objects, ['a', 'b']);
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(falsey, lodashStable.constant([objects[3], objects[1], objects[2], objects[0]]));
+
+      actual = lodashStable.map(falsey, function(order, index) {
+        return _.orderBy(objects, ['a', 'b'], index ? ['desc', order] : ['desc']);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `orders` specified as string objects', function(assert) {
+      assert.expect(1);
+
+      var actual = _.orderBy(objects, ['a'], [Object('desc')]);
+      assert.deepEqual(actual, [objects[1], objects[3], objects[0], objects[2]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.overArgs');
+
+  (function() {
+    function fn() {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should transform each argument', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, doubled, square);
+      assert.deepEqual(over(5, 10), [10, 100]);
+    });
+
+    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, undefined, null);
+      assert.deepEqual(over('a', 'b'), ['a', 'b']);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, 'b', 'a');
+      assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [2, 1]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, { 'b': 1 }, { 'a': 1 });
+      assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, ['b', 1], [['a', 1]]);
+      assert.deepEqual(over({ 'b': 2 }, { 'a': 1 }), [false, true]);
+    });
+
+    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overArgs(fn, ['a', 1]);
+      assert.deepEqual(over({ 'a': 1 }, { '1': 2 }), [1, 2]);
+
+      over = _.overArgs(fn, [['a', 1]]);
+      assert.deepEqual(over({ 'a': 1 }), [true]);
+    });
+
+    QUnit.test('should flatten `transforms`', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, [doubled, square], String);
+      assert.deepEqual(over(5, 10, 15), [10, 100, '15']);
+    });
+
+    QUnit.test('should not transform any argument greater than the number of transforms', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, doubled, square);
+      assert.deepEqual(over(5, 10, 18), [10, 100, 18]);
+    });
+
+    QUnit.test('should not transform any arguments if no transforms are given', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn);
+      assert.deepEqual(over(5, 10, 18), [5, 10, 18]);
+    });
+
+    QUnit.test('should not pass `undefined` if there are more transforms than arguments', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(fn, doubled, identity);
+      assert.deepEqual(over(5), [10]);
+    });
+
+    QUnit.test('should provide the correct argument to each transform', function(assert) {
+      assert.expect(1);
+
+      var argsList = [],
+          transform = function() { argsList.push(slice.call(arguments)); },
+          over = _.overArgs(noop, transform, transform, transform);
+
+      over('a', 'b');
+      assert.deepEqual(argsList, [['a'], ['b']]);
+    });
+
+    QUnit.test('should use `this` binding of function for `transforms`', function(assert) {
+      assert.expect(1);
+
+      var over = _.overArgs(function(x) {
+        return this[x];
+      }, function(x) {
+        return this === x;
+      });
+
+      var object = { 'over': over, 'true': 1 };
+      assert.strictEqual(object.over(object), 1);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.negate');
+
+  (function() {
+    QUnit.test('should create a function that negates the result of `func`', function(assert) {
+      assert.expect(2);
+
+      var negate = _.negate(isEven);
+
+      assert.strictEqual(negate(1), true);
+      assert.strictEqual(negate(2), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.noop');
+
+  (function() {
+    QUnit.test('should return `undefined`', function(assert) {
+      assert.expect(1);
+
+      var values = empties.concat(true, new Date, _, 1, /x/, 'a'),
+          expected = lodashStable.map(values, noop);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.noop(value) : _.noop();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.noConflict');
+
+  (function() {
+    QUnit.test('should return the `lodash` function', function(assert) {
+      assert.expect(2);
+
+      if (!isModularize) {
+        assert.strictEqual(_.noConflict(), oldDash);
+        assert.notStrictEqual(root._, oldDash);
+        root._ = oldDash;
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should restore `_` only if `lodash` is the current `_` value', function(assert) {
+      assert.expect(2);
+
+      if (!isModularize) {
+        var object = root._ = {};
+        assert.strictEqual(_.noConflict(), oldDash);
+        assert.strictEqual(root._, object);
+        root._ = oldDash;
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should work with a `root` of `this`', function(assert) {
+      assert.expect(2);
+
+      if (!isModularize && !coverage && (!document && realm.object)) {
+        var fs = require('fs'),
+            vm = require('vm'),
+            expected = {},
+            context = vm.createContext({ '_': expected, 'console': console }),
+            source = fs.readFileSync(filePath, 'utf8');
+
+        vm.runInContext(source + '\nthis.lodash = this._.noConflict()', context);
+
+        assert.strictEqual(context._, expected);
+        assert.ok(context.lodash);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.now');
+
+  (function() {
+    QUnit.test('should return the number of milliseconds that have elapsed since the Unix epoch', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var stamp = +new Date,
+          actual = _.now();
+
+      assert.ok(actual >= stamp);
+
+      setTimeout(function() {
+        assert.ok(_.now() > actual);
+        done();
+      }, 32);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.nth');
+
+  (function() {
+    var array = ['a', 'b', 'c', 'd'];
+
+    QUnit.test('should get the nth element of `array`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(array, function(value, index) {
+        return _.nth(array, index);
+      });
+
+      assert.deepEqual(actual, array);
+    });
+
+    QUnit.test('should work with a negative `n`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(lodashStable.range(1, array.length + 1), function(n) {
+        return _.nth(array, -n);
+      });
+
+      assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(2);
+
+      var values = falsey,
+          expected = lodashStable.map(values, alwaysA);
+
+      var actual = lodashStable.map(values, function(n) {
+        return n ? _.nth(array, n) : _.nth(array);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      values = ['1', 1.6];
+      expected = lodashStable.map(values, alwaysB);
+
+      actual = lodashStable.map(values, function(n) {
+        return _.nth(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `undefined` for empty arrays', function(assert) {
+      assert.expect(1);
+
+      var values = [null, undefined, []],
+          expected = lodashStable.map(values, noop);
+
+      var actual = lodashStable.map(values, function(array) {
+        return _.nth(array, 1);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `undefined` for non-indexes', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2],
+          values = [Infinity, array.length],
+          expected = lodashStable.map(values, noop);
+
+      array[-1] = 3;
+
+      var actual = lodashStable.map(values, function(n) {
+        return _.nth(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.nthArg');
+
+  (function() {
+    var args = ['a', 'b', 'c', 'd'];
+
+    QUnit.test('should create a function that returns its nth argument', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(args, function(value, index) {
+        var func = _.nthArg(index);
+        return func.apply(undefined, args);
+      });
+
+      assert.deepEqual(actual, args);
+    });
+
+    QUnit.test('should work with a negative `n`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(lodashStable.range(1, args.length + 1), function(n) {
+        var func = _.nthArg(-n);
+        return func.apply(undefined, args);
+      });
+
+      assert.deepEqual(actual, ['d', 'c', 'b', 'a']);
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(2);
+
+      var values = falsey,
+          expected = lodashStable.map(values, alwaysA);
+
+      var actual = lodashStable.map(values, function(n) {
+        var func = n ? _.nthArg(n) : _.nthArg();
+        return func.apply(undefined, args);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      values = ['1', 1.6];
+      expected = lodashStable.map(values, alwaysB);
+
+      actual = lodashStable.map(values, function(n) {
+        var func = _.nthArg(n);
+        return func.apply(undefined, args);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `undefined` for empty arrays', function(assert) {
+      assert.expect(1);
+
+      var func = _.nthArg(1);
+      assert.strictEqual(func(), undefined);
+    });
+
+    QUnit.test('should return `undefined` for non-indexes', function(assert) {
+      assert.expect(1);
+
+      var values = [Infinity, args.length],
+          expected = lodashStable.map(values, noop);
+
+      var actual = lodashStable.map(values, function(n) {
+        var func = _.nthArg(n);
+        return func.apply(undefined, args);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.omit');
+
+  (function() {
+    var args = arguments,
+        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
+
+    QUnit.test('should flatten `props`', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.omit(object, 'a', 'c'), { 'b': 2, 'd': 4 });
+      assert.deepEqual(_.omit(object, ['a', 'd'], 'c'), { 'b': 2 });
+    });
+
+    QUnit.test('should work with a primitive `object` argument', function(assert) {
+      assert.expect(1);
+
+      stringProto.a = 1;
+      stringProto.b = 2;
+
+      assert.deepEqual(_.omit('', 'b'), { 'a': 1 });
+
+      delete stringProto.a;
+      delete stringProto.b;
+    });
+
+    QUnit.test('should return an empty object when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      objectProto.a = 1;
+      lodashStable.each([null, undefined], function(value) {
+        assert.deepEqual(_.omit(value, 'valueOf'), {});
+      });
+      delete objectProto.a;
+    });
+
+    QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.omit(object, args), { 'b': 2, 'd': 4 });
+    });
+
+    QUnit.test('should coerce property names to strings', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.omit({ '0': 'a' }, 0), {});
+    });
+  }('a', 'c'));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.omitBy');
+
+  (function() {
+    QUnit.test('should work with a predicate argument', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
+
+      var actual = _.omitBy(object, function(n) {
+        return n != 2 && n != 4;
+      });
+
+      assert.deepEqual(actual, { 'b': 2, 'd': 4 });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('omit methods');
+
+  lodashStable.each(['omit', 'omitBy'], function(methodName) {
+    var expected = { 'b': 2, 'd': 4 },
+        func = _[methodName],
+        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
+        prop = lodashStable.nthArg(1);
+
+    if (methodName == 'omitBy') {
+      prop = function(object, props) {
+        props = lodashStable.castArray(props);
+        return function(value) {
+          return lodashStable.some(props, function(key) {
+            key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
+            return object[key] === value;
+          });
+        };
+      };
+    }
+    QUnit.test('`_.' + methodName + '` should create an object with omitted string keyed properties', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(func(object, prop(object, 'a')), { 'b': 2, 'c': 3, 'd': 4 });
+      assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should include inherited string keyed properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype = object;
+
+      assert.deepEqual(func(new Foo, prop(object, ['a', 'c'])), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': 'a', '0': 'b' },
+          props = [-0, Object(-0), 0, Object(0)],
+          expected = [{ '0': 'b' }, { '0': 'b' }, { '-0': 'a' }, { '-0': 'a' }];
+
+      var actual = lodashStable.map(props, function(key) {
+        return func(object, prop(object, key));
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should include symbol properties', function(assert) {
+      assert.expect(2);
+
+      function Foo() {
+        this.a = 0;
+        this[symbol] = 1;
+      }
+
+      if (Symbol) {
+        var symbol2 = Symbol('b');
+        Foo.prototype[symbol2] = 2;
+
+        var foo = new Foo,
+            actual = func(foo, prop(foo, 'a'));
+
+        assert.strictEqual(actual[symbol], 1);
+        assert.strictEqual(actual[symbol2], 2);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should create an object with omitted symbol properties', function(assert) {
+      assert.expect(6);
+
+      function Foo() {
+        this.a = 0;
+        this[symbol] = 1;
+      }
+
+      if (Symbol) {
+        var symbol2 = Symbol('b');
+        Foo.prototype[symbol2] = 2;
+
+        var foo = new Foo,
+            actual = func(foo, prop(foo, symbol));
+
+        assert.strictEqual(actual.a, 0);
+        assert.strictEqual(actual[symbol], undefined);
+        assert.strictEqual(actual[symbol2], 2);
+
+        actual = func(foo, prop(foo, symbol2));
+
+        assert.strictEqual(actual.a, 0);
+        assert.strictEqual(actual[symbol], 1);
+        assert.strictEqual(actual[symbol2], undefined);
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(func(array, prop(array, ['0', '2'])), { '1': 2 });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.once');
+
+  (function() {
+    QUnit.test('should invoke `func` once', function(assert) {
+      assert.expect(2);
+
+      var count = 0,
+          once = _.once(function() { return ++count; });
+
+      once();
+      assert.strictEqual(once(), 1);
+      assert.strictEqual(count, 1);
+    });
+
+    QUnit.test('should ignore recursive calls', function(assert) {
+      assert.expect(2);
+
+      var count = 0;
+
+      var once = _.once(function() {
+        once();
+        return ++count;
+      });
+
+      assert.strictEqual(once(), 1);
+      assert.strictEqual(count, 1);
+    });
+
+    QUnit.test('should not throw more than once', function(assert) {
+      assert.expect(2);
+
+      var pass = true;
+
+      var once = _.once(function() {
+        throw new Error;
+      });
+
+      assert.raises(once);
+
+      try {
+        once();
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.over');
+
+  (function() {
+    QUnit.test('should create a function that invokes `iteratees`', function(assert) {
+      assert.expect(1);
+
+      var over = _.over(Math.max, Math.min);
+      assert.deepEqual(over(1, 2, 3, 4), [4, 1]);
+    });
+
+    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
+      assert.expect(1);
+
+      var over = _.over(undefined, null);
+      assert.deepEqual(over('a', 'b', 'c'), ['a', 'a']);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var over = _.over('b', 'a');
+      assert.deepEqual(over({ 'a': 1, 'b': 2 }), [2, 1]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      var over = _.over({ 'b': 1 }, { 'a': 1 });
+      assert.deepEqual(over({ 'a': 1, 'b': 2 }), [false, true]);
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.over(['b', 2], [['a', 2]]);
+
+      assert.deepEqual(over({ 'a': 1, 'b': 2 }), [true, false]);
+      assert.deepEqual(over({ 'a': 2, 'b': 1 }), [false, true]);
+    });
+
+    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(4);
+
+      var over = _.over(['a', 1]);
+
+      assert.deepEqual(over({ 'a': 1, '1': 2 }), [1, 2]);
+      assert.deepEqual(over({ 'a': 2, '1': 1 }), [2, 1]);
+
+      over = _.over([['a', 1]]);
+
+      assert.deepEqual(over({ 'a': 1 }), [true]);
+      assert.deepEqual(over({ 'a': 2 }), [false]);
+    });
+
+    QUnit.test('should provide arguments to predicates', function(assert) {
+      assert.expect(1);
+
+      var over = _.over(function() {
+        return slice.call(arguments);
+      });
+
+      assert.deepEqual(over('a', 'b', 'c'), [['a', 'b', 'c']]);
+    });
+
+    QUnit.test('should use `this` binding of function for `iteratees`', function(assert) {
+      assert.expect(1);
+
+      var over = _.over(function() { return this.b; }, function() { return this.a; }),
+          object = { 'over': over, 'a': 1, 'b': 2 };
+
+      assert.deepEqual(object.over(), [2, 1]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.overEvery');
+
+  (function() {
+    QUnit.test('should create a function that returns `true` if all predicates return truthy', function(assert) {
+      assert.expect(1);
+
+      var over = _.overEvery(alwaysTrue, alwaysOne, alwaysA);
+      assert.strictEqual(over(), true);
+    });
+
+    QUnit.test('should return `false` as soon as a predicate returns falsey', function(assert) {
+      assert.expect(2);
+
+      var count = 0,
+          countFalse = function() { count++; return false; },
+          countTrue = function() { count++; return true; },
+          over = _.overEvery(countTrue, countFalse, countTrue);
+
+      assert.strictEqual(over(), false);
+      assert.strictEqual(count, 2);
+    });
+
+    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
+      assert.expect(2);
+
+      var over = _.overEvery(undefined, null);
+
+      assert.strictEqual(over(true), true);
+      assert.strictEqual(over(false), false);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overEvery('b', 'a');
+
+      assert.strictEqual(over({ 'a': 1, 'b': 1 }), true);
+      assert.strictEqual(over({ 'a': 0, 'b': 1 }), false);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overEvery({ 'b': 2 }, { 'a': 1 });
+
+      assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
+      assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overEvery(['b', 2], [['a', 1]]);
+
+      assert.strictEqual(over({ 'a': 1, 'b': 2 }), true);
+      assert.strictEqual(over({ 'a': 0, 'b': 2 }), false);
+    });
+
+    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(5);
+
+      var over = _.overEvery(['a', 1]);
+
+      assert.strictEqual(over({ 'a': 1, '1': 1 }), true);
+      assert.strictEqual(over({ 'a': 1, '1': 0 }), false);
+      assert.strictEqual(over({ 'a': 0, '1': 1 }), false);
+
+      over = _.overEvery([['a', 1]]);
+
+      assert.strictEqual(over({ 'a': 1 }), true);
+      assert.strictEqual(over({ 'a': 2 }), false);
+    });
+
+    QUnit.test('should flatten `predicates`', function(assert) {
+      assert.expect(1);
+
+      var over = _.overEvery(alwaysTrue, [alwaysFalse]);
+      assert.strictEqual(over(), false);
+    });
+
+    QUnit.test('should provide arguments to predicates', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      var over = _.overEvery(function() {
+        args = slice.call(arguments);
+      });
+
+      over('a', 'b', 'c');
+      assert.deepEqual(args, ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
+      assert.expect(2);
+
+      var over = _.overEvery(function() { return this.b; }, function() { return this.a; }),
+          object = { 'over': over, 'a': 1, 'b': 2 };
+
+      assert.strictEqual(object.over(), true);
+
+      object.a = 0;
+      assert.strictEqual(object.over(), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.overSome');
+
+  (function() {
+    QUnit.test('should create a function that returns `true` if any predicates return truthy', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome(alwaysFalse, alwaysOne, alwaysEmptyString);
+      assert.strictEqual(over(), true);
+
+      over = _.overSome(alwaysNull, alwaysA, alwaysZero);
+      assert.strictEqual(over(), true);
+    });
+
+    QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
+      assert.expect(2);
+
+      var count = 0,
+          countFalse = function() { count++; return false; },
+          countTrue = function() { count++; return true; },
+          over = _.overSome(countFalse, countTrue, countFalse);
+
+      assert.strictEqual(over(), true);
+      assert.strictEqual(count, 2);
+    });
+
+    QUnit.test('should return `false` if all predicates return falsey', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome(alwaysFalse, alwaysFalse, alwaysFalse);
+      assert.strictEqual(over(), false);
+
+      over = _.overSome(alwaysNull, alwaysZero, alwaysEmptyString);
+      assert.strictEqual(over(), false);
+    });
+
+    QUnit.test('should use `_.identity` when a predicate is nullish', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome(undefined, null);
+
+      assert.strictEqual(over(true), true);
+      assert.strictEqual(over(false), false);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome('b', 'a');
+
+      assert.strictEqual(over({ 'a': 1, 'b': 0 }), true);
+      assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome({ 'b': 2 }, { 'a': 1 });
+
+      assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
+      assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome(['a', 1], [['b', 2]]);
+
+      assert.strictEqual(over({ 'a': 0, 'b': 2 }), true);
+      assert.strictEqual(over({ 'a': 0, 'b': 0 }), false);
+    });
+
+    QUnit.test('should differentiate between `_.property` and `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(5);
+
+      var over = _.overSome(['a', 1]);
+
+      assert.strictEqual(over({ 'a': 0, '1': 0 }), false);
+      assert.strictEqual(over({ 'a': 1, '1': 0 }), true);
+      assert.strictEqual(over({ 'a': 0, '1': 1 }), true);
+
+      over = _.overSome([['a', 1]]);
+
+      assert.strictEqual(over({ 'a': 1 }), true);
+      assert.strictEqual(over({ 'a': 2 }), false);
+    });
+
+    QUnit.test('should flatten `predicates`', function(assert) {
+      assert.expect(1);
+
+      var over = _.overSome(alwaysFalse, [alwaysTrue]);
+      assert.strictEqual(over(), true);
+    });
+
+    QUnit.test('should provide arguments to predicates', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      var over = _.overSome(function() {
+        args = slice.call(arguments);
+      });
+
+      over('a', 'b', 'c');
+      assert.deepEqual(args, ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should use `this` binding of function for `predicates`', function(assert) {
+      assert.expect(2);
+
+      var over = _.overSome(function() { return this.b; }, function() { return this.a; }),
+          object = { 'over': over, 'a': 1, 'b': 2 };
+
+      assert.strictEqual(object.over(), true);
+
+      object.a = object.b = 0;
+      assert.strictEqual(object.over(), false);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.pad');
+
+  (function() {
+    var string = 'abc';
+
+    QUnit.test('should pad a string to a given length', function(assert) {
+      assert.expect(1);
+
+      var values = [, undefined],
+          expected = lodashStable.map(values, lodashStable.constant(' abc  '));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.pad(string, 6, value) : _.pad(string, 6);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.pad(string, 8), '  abc   ');
+      assert.strictEqual(_.pad(string, 8, '_-'), '_-abc_-_');
+    });
+
+    QUnit.test('should coerce `string` to a string', function(assert) {
+      assert.expect(1);
+
+      var values = [Object(string), { 'toString': lodashStable.constant(string) }],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.pad(value, 6) === ' abc  ';
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.padEnd');
+
+  (function() {
+    var string = 'abc';
+
+    QUnit.test('should pad a string to a given length', function(assert) {
+      assert.expect(1);
+
+      var values = [, undefined],
+          expected = lodashStable.map(values, lodashStable.constant('abc   '));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.padEnd(string, 6, value) : _.padEnd(string, 6);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.padEnd(string, 6, '_-'), 'abc_-_');
+    });
+
+    QUnit.test('should coerce `string` to a string', function(assert) {
+      assert.expect(1);
+
+      var values = [Object(string), { 'toString': lodashStable.constant(string) }],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.padEnd(value, 6) === 'abc   ';
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.padStart');
+
+  (function() {
+    var string = 'abc';
+
+    QUnit.test('should pad a string to a given length', function(assert) {
+      assert.expect(1);
+
+      var values = [, undefined],
+          expected = lodashStable.map(values, lodashStable.constant('   abc'));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.padStart(string, 6, value) : _.padStart(string, 6);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should truncate pad characters to fit the pad length', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.padStart(string, 6, '_-'), '_-_abc');
+    });
+
+    QUnit.test('should coerce `string` to a string', function(assert) {
+      assert.expect(1);
+
+      var values = [Object(string), { 'toString': lodashStable.constant(string) }],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.padStart(value, 6) === '   abc';
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('pad methods');
+
+  lodashStable.each(['pad', 'padStart', 'padEnd'], function(methodName) {
+    var func = _[methodName],
+        isPad = methodName == 'pad',
+        isStart = methodName == 'padStart',
+        string = 'abc';
+
+    QUnit.test('`_.' + methodName + '` should not pad if string is >= `length`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(func(string, 2), string);
+      assert.strictEqual(func(string, 3), string);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat negative `length` as `0`', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([0, -2], function(length) {
+        assert.strictEqual(func(string, length), string);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `length` to a number', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each(['', '4'], function(length) {
+        var actual = length ? (isStart ? ' abc' : 'abc ') : string;
+        assert.strictEqual(func(string, length), actual);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat nullish values as empty strings', function(assert) {
+      assert.expect(6);
+
+      lodashStable.each([undefined, '_-'], function(chars) {
+        var expected = chars ? (isPad ? '__' : chars) : '  ';
+        assert.strictEqual(func(null, 2, chars), expected);
+        assert.strictEqual(func(undefined, 2, chars), expected);
+        assert.strictEqual(func('', 2, chars), expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `string` when `chars` coerces to an empty string', function(assert) {
+      assert.expect(1);
+
+      var values = ['', Object('')],
+          expected = lodashStable.map(values, lodashStable.constant(string));
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.pad(string, 6, value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.parseInt');
+
+  (function() {
+    QUnit.test('should accept a `radix` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.range(2, 37);
+
+      var actual = lodashStable.map(expected, function(radix) {
+        return _.parseInt('10', radix);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should use a radix of `10`, for non-hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.parseInt('10'), 10);
+      assert.strictEqual(_.parseInt('10', 0), 10);
+      assert.strictEqual(_.parseInt('10', 10), 10);
+      assert.strictEqual(_.parseInt('10', undefined), 10);
+    });
+
+    QUnit.test('should use a radix of `16`, for hexadecimals, if `radix` is `undefined` or `0`', function(assert) {
+      assert.expect(8);
+
+      lodashStable.each(['0x20', '0X20'], function(string) {
+        assert.strictEqual(_.parseInt(string), 32);
+        assert.strictEqual(_.parseInt(string, 0), 32);
+        assert.strictEqual(_.parseInt(string, 16), 32);
+        assert.strictEqual(_.parseInt(string, undefined), 32);
+      });
+    });
+
+    QUnit.test('should use a radix of `10` for string with leading zeros', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.parseInt('08'), 8);
+      assert.strictEqual(_.parseInt('08', 10), 8);
+    });
+
+    QUnit.test('should parse strings with leading whitespace (test in Chrome and Firefox)', function(assert) {
+      assert.expect(2);
+
+      var expected = [8, 8, 10, 10, 32, 32, 32, 32];
+
+      lodashStable.times(2, function(index) {
+        var actual = [],
+            func = (index ? (lodashBizarro || {}) : _).parseInt;
+
+        if (func) {
+          lodashStable.times(2, function(otherIndex) {
+            var string = otherIndex ? '10' : '08';
+            actual.push(
+              func(whitespace + string, 10),
+              func(whitespace + string)
+            );
+          });
+
+          lodashStable.each(['0x20', '0X20'], function(string) {
+            actual.push(
+              func(whitespace + string),
+              func(whitespace + string, 16)
+            );
+          });
+
+          assert.deepEqual(actual, expected);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    QUnit.test('should coerce `radix` to a number', function(assert) {
+      assert.expect(2);
+
+      var object = { 'valueOf': alwaysZero };
+      assert.strictEqual(_.parseInt('08', object), 8);
+      assert.strictEqual(_.parseInt('0x20', object), 32);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(2);
+
+      var strings = lodashStable.map(['6', '08', '10'], Object),
+          actual = lodashStable.map(strings, _.parseInt);
+
+      assert.deepEqual(actual, [6, 8, 10]);
+
+      actual = lodashStable.map('123', _.parseInt);
+      assert.deepEqual(actual, [1, 2, 3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('partial methods');
+
+  lodashStable.each(['partial', 'partialRight'], function(methodName) {
+    var func = _[methodName],
+        isPartial = methodName == 'partial',
+        ph = func.placeholder;
+
+    QUnit.test('`_.' + methodName + '` partially applies arguments', function(assert) {
+      assert.expect(1);
+
+      var par = func(identity, 'a');
+      assert.strictEqual(par(), 'a');
+    });
+
+    QUnit.test('`_.' + methodName + '` creates a function that can be invoked with additional arguments', function(assert) {
+      assert.expect(1);
+
+      var fn = function(a, b) { return [a, b]; },
+          par = func(fn, 'a'),
+          expected = isPartial ? ['a', 'b'] : ['b', 'a'];
+
+      assert.deepEqual(par('b'), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked without additional arguments', function(assert) {
+      assert.expect(1);
+
+      var fn = function() { return arguments.length; },
+          par = func(fn);
+
+      assert.strictEqual(par(), 0);
+    });
+
+    QUnit.test('`_.' + methodName + '` works when there are no partially applied arguments and the created function is invoked with additional arguments', function(assert) {
+      assert.expect(1);
+
+      var par = func(identity);
+      assert.strictEqual(par('a'), 'a');
+    });
+
+    QUnit.test('`_.' + methodName + '` should support placeholders', function(assert) {
+      assert.expect(4);
+
+      var fn = function() { return slice.call(arguments); },
+          par = func(fn, ph, 'b', ph);
+
+      assert.deepEqual(par('a', 'c'), ['a', 'b', 'c']);
+      assert.deepEqual(par('a'), ['a', 'b', undefined]);
+      assert.deepEqual(par(), [undefined, 'b', undefined]);
+
+      if (isPartial) {
+        assert.deepEqual(par('a', 'c', 'd'), ['a', 'b', 'c', 'd']);
+      } else {
+        par = func(fn, ph, 'c', ph);
+        assert.deepEqual(par('a', 'b', 'd'), ['a', 'b', 'c', 'd']);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should use `_.placeholder` when set', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var _ph = _.placeholder = {},
+            fn = function() { return slice.call(arguments); },
+            par = func(fn, _ph, 'b', ph),
+            expected = isPartial ? ['a', 'b', ph, 'c'] : ['a', 'c', 'b', ph];
+
+        assert.deepEqual(par('a', 'c'), expected);
+        delete _.placeholder;
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` creates a function with a `length` of `0`', function(assert) {
+      assert.expect(1);
+
+      var fn = function(a, b, c) {},
+          par = func(fn, 'a');
+
+      assert.strictEqual(par.length, 0);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ensure `new par` is an instance of `func`', function(assert) {
+      assert.expect(2);
+
+      function Foo(value) {
+        return value && object;
+      }
+
+      var object = {},
+          par = func(Foo);
+
+      assert.ok(new par instanceof Foo);
+      assert.strictEqual(new par(true), object);
+    });
+
+    QUnit.test('`_.' + methodName + '` should clone metadata for created functions', function(assert) {
+      assert.expect(3);
+
+      function greet(greeting, name) {
+        return greeting + ' ' + name;
+      }
+
+      var par1 = func(greet, 'hi'),
+          par2 = func(par1, 'barney'),
+          par3 = func(par1, 'pebbles');
+
+      assert.strictEqual(par1('fred'), isPartial ? 'hi fred' : 'fred hi');
+      assert.strictEqual(par2(), isPartial ? 'hi barney'  : 'barney hi');
+      assert.strictEqual(par3(), isPartial ? 'hi pebbles' : 'pebbles hi');
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with curried functions', function(assert) {
+      assert.expect(2);
+
+      var fn = function(a, b, c) { return a + b + c; },
+          curried = _.curry(func(fn, 1), 2);
+
+      assert.strictEqual(curried(2, 3), 6);
+      assert.strictEqual(curried(2)(3), 6);
+    });
+
+    QUnit.test('should work with placeholders and curried functions', function(assert) {
+      assert.expect(1);
+
+      var fn = function() { return slice.call(arguments); },
+          curried = _.curry(fn),
+          par = func(curried, ph, 'b', ph, 'd');
+
+      assert.deepEqual(par('a', 'c'), ['a', 'b', 'c', 'd']);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.partialRight');
+
+  (function() {
+    QUnit.test('should work as a deep `_.defaults`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': { 'b': 1 } },
+          source = { 'a': { 'b': 2, 'c': 3 } },
+          expected = { 'a': { 'b': 1, 'c': 3 } };
+
+      var defaultsDeep = _.partialRight(_.mergeWith, function deep(value, other) {
+        return lodashStable.isObject(value) ? _.mergeWith(value, other, deep) : value;
+      });
+
+      assert.deepEqual(defaultsDeep(object, source), expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('methods using `createWrapper`');
+
+  (function() {
+    function fn() {
+      return slice.call(arguments);
+    }
+
+    var ph1 = _.bind.placeholder,
+        ph2 = _.bindKey.placeholder,
+        ph3 = _.partial.placeholder,
+        ph4 = _.partialRight.placeholder;
+
+    QUnit.test('should work with combinations of partial functions', function(assert) {
+      assert.expect(1);
+
+      var a = _.partial(fn),
+          b = _.partialRight(a, 3),
+          c = _.partial(b, 1);
+
+      assert.deepEqual(c(2), [1, 2, 3]);
+    });
+
+    QUnit.test('should work with combinations of bound and partial functions', function(assert) {
+      assert.expect(3);
+
+      var fn = function() {
+        var result = [this.a];
+        push.apply(result, arguments);
+        return result;
+      };
+
+      var expected = [1, 2, 3, 4],
+          object = { 'a': 1, 'fn': fn };
+
+      var a = _.bindKey(object, 'fn'),
+          b = _.partialRight(a, 4),
+          c = _.partial(b, 2);
+
+      assert.deepEqual(c(3), expected);
+
+      a = _.bind(fn, object);
+      b = _.partialRight(a, 4);
+      c = _.partial(b, 2);
+
+      assert.deepEqual(c(3), expected);
+
+      a = _.partial(fn, 2);
+      b = _.bind(a, object);
+      c = _.partialRight(b, 4);
+
+      assert.deepEqual(c(3), expected);
+    });
+
+    QUnit.test('should ensure `new combo` is an instance of `func`', function(assert) {
+      assert.expect(2);
+
+      function Foo(a, b, c) {
+        return b === 0 && object;
+      }
+
+      var combo = _.partial(_.partialRight(Foo, 3), 1),
+          object = {};
+
+      assert.ok(new combo(2) instanceof Foo);
+      assert.strictEqual(new combo(0), object);
+    });
+
+    QUnit.test('should work with combinations of functions with placeholders', function(assert) {
+      assert.expect(3);
+
+      var expected = [1, 2, 3, 4, 5, 6],
+          object = { 'fn': fn };
+
+      var a = _.bindKey(object, 'fn', ph2, 2),
+          b = _.partialRight(a, ph4, 6),
+          c = _.partial(b, 1, ph3, 4);
+
+      assert.deepEqual(c(3, 5), expected);
+
+      a = _.bind(fn, object, ph1, 2);
+      b = _.partialRight(a, ph4, 6);
+      c = _.partial(b, 1, ph3, 4);
+
+      assert.deepEqual(c(3, 5), expected);
+
+      a = _.partial(fn, ph3, 2);
+      b = _.bind(a, object, 1, ph1, 4);
+      c = _.partialRight(b, ph4, 6);
+
+      assert.deepEqual(c(3, 5), expected);
+    });
+
+    QUnit.test('should work with combinations of functions with overlapping placeholders', function(assert) {
+      assert.expect(3);
+
+      var expected = [1, 2, 3, 4],
+          object = { 'fn': fn };
+
+      var a = _.bindKey(object, 'fn', ph2, 2),
+          b = _.partialRight(a, ph4, 4),
+          c = _.partial(b, ph3, 3);
+
+      assert.deepEqual(c(1), expected);
+
+      a = _.bind(fn, object, ph1, 2);
+      b = _.partialRight(a, ph4, 4);
+      c = _.partial(b, ph3, 3);
+
+      assert.deepEqual(c(1), expected);
+
+      a = _.partial(fn, ph3, 2);
+      b = _.bind(a, object, ph1, 3);
+      c = _.partialRight(b, ph4, 4);
+
+      assert.deepEqual(c(1), expected);
+    });
+
+    QUnit.test('should work with recursively bound functions', function(assert) {
+      assert.expect(1);
+
+      var fn = function() {
+        return this.a;
+      };
+
+      var a = _.bind(fn, { 'a': 1 }),
+          b = _.bind(a,  { 'a': 2 }),
+          c = _.bind(b,  { 'a': 3 });
+
+      assert.strictEqual(c(), 1);
+    });
+
+    QUnit.test('should work when hot', function(assert) {
+      assert.expect(12);
+
+      lodashStable.times(2, function(index) {
+        var fn = function() {
+          var result = [this];
+          push.apply(result, arguments);
+          return result;
+        };
+
+        var object = {},
+            bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
+            expected = [object, 1, 2, 3];
+
+        var actual = _.last(lodashStable.times(HOT_COUNT, function() {
+          var bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
+          return index ? bound2(3) : bound2(1, 2, 3);
+        }));
+
+        assert.deepEqual(actual, expected);
+
+        actual = _.last(lodashStable.times(HOT_COUNT, function() {
+          var bound1 = index ? _.bind(fn, object, 1) : _.bind(fn, object),
+              bound2 = index ? _.bind(bound1, null, 2) : _.bind(bound1);
+
+          return index ? bound2(3) : bound2(1, 2, 3);
+        }));
+
+        assert.deepEqual(actual, expected);
+      });
+
+      lodashStable.each(['curry', 'curryRight'], function(methodName, index) {
+        var fn = function(a, b, c) { return [a, b, c]; },
+            curried = _[methodName](fn),
+            expected = index ? [3, 2, 1] :  [1, 2, 3];
+
+        var actual = _.last(lodashStable.times(HOT_COUNT, function() {
+          return curried(1)(2)(3);
+        }));
+
+        assert.deepEqual(actual, expected);
+
+        actual = _.last(lodashStable.times(HOT_COUNT, function() {
+          var curried = _[methodName](fn);
+          return curried(1)(2)(3);
+        }));
+
+        assert.deepEqual(actual, expected);
+      });
+
+      lodashStable.each(['partial', 'partialRight'], function(methodName, index) {
+        var func = _[methodName],
+            fn = function() { return slice.call(arguments); },
+            par1 = func(fn, 1),
+            expected = index ? [3, 2, 1] : [1, 2, 3];
+
+        var actual = _.last(lodashStable.times(HOT_COUNT, function() {
+          var par2 = func(par1, 2);
+          return par2(3);
+        }));
+
+        assert.deepEqual(actual, expected);
+
+        actual = _.last(lodashStable.times(HOT_COUNT, function() {
+          var par1 = func(fn, 1),
+              par2 = func(par1, 2);
+
+          return par2(3);
+        }));
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.partition');
+
+  (function() {
+    var array = [1, 0, 1];
+
+    QUnit.test('should split elements into two groups by `predicate`', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(_.partition([], identity), [[], []]);
+      assert.deepEqual(_.partition(array, alwaysTrue), [array, []]);
+      assert.deepEqual(_.partition(array, alwaysFalse), [[], array]);
+    });
+
+    QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([[1, 1], [0]]));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.partition(array, value) : _.partition(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': 1 }, { 'a': 1 }, { 'b': 2 }],
+          actual = _.partition(objects, 'a');
+
+      assert.deepEqual(actual, [objects.slice(0, 2), objects.slice(2)]);
+    });
+
+    QUnit.test('should work with a number for `predicate`', function(assert) {
+      assert.expect(2);
+
+      var array = [
+        [1, 0],
+        [0, 1],
+        [1, 0]
+      ];
+
+      assert.deepEqual(_.partition(array, 0), [[array[0], array[2]], [array[1]]]);
+      assert.deepEqual(_.partition(array, 1), [[array[1]], [array[0], array[2]]]);
+    });
+
+    QUnit.test('should work with an object for `collection`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.partition({ 'a': 1.1, 'b': 0.2, 'c': 1.3 }, Math.floor);
+      assert.deepEqual(actual, [[1.1, 1.3], [0.2]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.pick');
+
+  (function() {
+    var args = arguments,
+        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
+
+    QUnit.test('should flatten `props`', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.pick(object, 'a', 'c'), { 'a': 1, 'c': 3 });
+      assert.deepEqual(_.pick(object, ['a', 'd'], 'c'), { 'a': 1, 'c': 3, 'd': 4 });
+    });
+
+    QUnit.test('should work with a primitive `object` argument', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.pick('', 'slice'), { 'slice': ''.slice });
+    });
+
+    QUnit.test('should return an empty object when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([null, undefined], function(value) {
+        assert.deepEqual(_.pick(value, 'valueOf'), {});
+      });
+    });
+
+    QUnit.test('should work with `arguments` objects as secondary arguments', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.pick(object, args), { 'a': 1, 'c': 3 });
+    });
+
+    QUnit.test('should coerce property names to strings', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.pick({ '0': 'a', '1': 'b' }, 0), { '0': 'a' });
+    });
+  }('a', 'c'));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.pickBy');
+
+  (function() {
+    QUnit.test('should work with a predicate argument', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };
+
+      var actual = _.pickBy(object, function(n) {
+        return n == 1 || n == 3;
+      });
+
+      assert.deepEqual(actual, { 'a': 1, 'c': 3 });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('pick methods');
+
+  lodashStable.each(['pick', 'pickBy'], function(methodName) {
+    var expected = { 'a': 1, 'c': 3 },
+        func = _[methodName],
+        object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
+        prop = lodashStable.nthArg(1);
+
+    if (methodName == 'pickBy') {
+      prop = function(object, props) {
+        props = lodashStable.castArray(props);
+        return function(value) {
+          return lodashStable.some(props, function(key) {
+            key = lodashStable.isSymbol(key) ? key : lodashStable.toString(key);
+            return object[key] === value;
+          });
+        };
+      };
+    }
+    QUnit.test('`_.' + methodName + '` should create an object of picked string keyed properties', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(func(object, prop(object, 'a')), { 'a': 1 });
+      assert.deepEqual(func(object, prop(object, ['a', 'c'])), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should pick inherited string keyed properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {}
+      Foo.prototype = object;
+
+      var foo = new Foo;
+      assert.deepEqual(func(foo, prop(foo, ['a', 'c'])), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': 'a', '0': 'b' },
+          props = [-0, Object(-0), 0, Object(0)],
+          expected = [{ '-0': 'a' }, { '-0': 'a' }, { '0': 'b' }, { '0': 'b' }];
+
+      var actual = lodashStable.map(props, function(key) {
+        return func(object, prop(object, key));
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should pick symbol properties', function(assert) {
+      assert.expect(2);
+
+      function Foo() {
+        this[symbol] = 1;
+      }
+
+      if (Symbol) {
+        var symbol2 = Symbol('b');
+        Foo.prototype[symbol2] = 2;
+
+        var foo = new Foo,
+            actual = func(foo, prop(foo, [symbol, symbol2]));
+
+        assert.strictEqual(actual[symbol], 1);
+        assert.strictEqual(actual[symbol2], 2);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with an array `object` argument', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      assert.deepEqual(func(array, prop(array, '1')), { '1': 2 });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.property');
+
+  (function() {
+    QUnit.test('should create a function that plucks a property value of a given object', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': 1 };
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var prop = _.property(path);
+        assert.strictEqual(prop.length, 1);
+        assert.strictEqual(prop(object), 1);
+      });
+    });
+
+    QUnit.test('should pluck deep property values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var prop = _.property(path);
+        assert.strictEqual(prop(object), 2);
+      });
+    });
+
+    QUnit.test('should pluck inherited property values', function(assert) {
+      assert.expect(2);
+
+      function Foo() {}
+      Foo.prototype.a = 1;
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var prop = _.property(path);
+        assert.strictEqual(prop(new Foo), 1);
+      });
+    });
+
+    QUnit.test('should work with a non-string `path`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3];
+
+      lodashStable.each([1, [1]], function(path) {
+        var prop = _.property(path);
+        assert.strictEqual(prop(array), 2);
+      });
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': 'a', '0': 'b' },
+          props = [-0, Object(-0), 0, Object(0)];
+
+      var actual = lodashStable.map(props, function(key) {
+        var prop = _.property(key);
+        return prop(object);
+      });
+
+      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
+    });
+
+    QUnit.test('should coerce key to a string', function(assert) {
+      assert.expect(1);
+
+      function fn() {}
+      fn.toString = lodashStable.constant('fn');
+
+      var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
+          values = [null, undefined, fn, {}];
+
+      var actual = lodashStable.transform(objects, function(result, object, index) {
+        var key = values[index];
+        lodashStable.each([key, [key]], function(path) {
+          var prop = _.property(key);
+          result.push(prop(object));
+        });
+      });
+
+      assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
+    });
+
+    QUnit.test('should pluck a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': 1, 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        var prop = _.property(path);
+        assert.strictEqual(prop(object), 1);
+      });
+    });
+
+    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        var prop = _.property(path);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? prop(value) : prop();
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
+        var prop = _.property(path);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? prop(value) : prop();
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
+      assert.expect(4);
+
+      var object = {};
+
+      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
+        var prop = _.property(path);
+        assert.strictEqual(prop(object), undefined);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.propertyOf');
+
+  (function() {
+    QUnit.test('should create a function that plucks a property value of a given key', function(assert) {
+      assert.expect(3);
+
+      var object = { 'a': 1 },
+          propOf = _.propertyOf(object);
+
+      assert.strictEqual(propOf.length, 1);
+      lodashStable.each(['a', ['a']], function(path) {
+        assert.strictEqual(propOf(path), 1);
+      });
+    });
+
+    QUnit.test('should pluck deep property values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': 2 } },
+          propOf = _.propertyOf(object);
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(propOf(path), 2);
+      });
+    });
+
+    QUnit.test('should pluck inherited property values', function(assert) {
+      assert.expect(2);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var propOf = _.propertyOf(new Foo);
+
+      lodashStable.each(['b', ['b']], function(path) {
+        assert.strictEqual(propOf(path), 2);
+      });
+    });
+
+    QUnit.test('should work with a non-string `path`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          propOf = _.propertyOf(array);
+
+      lodashStable.each([1, [1]], function(path) {
+        assert.strictEqual(propOf(path), 2);
+      });
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': 'a', '0': 'b' },
+          props = [-0, Object(-0), 0, Object(0)];
+
+      var actual = lodashStable.map(props, function(key) {
+        var propOf = _.propertyOf(object);
+        return propOf(key);
+      });
+
+      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
+    });
+
+    QUnit.test('should coerce key to a string', function(assert) {
+      assert.expect(1);
+
+      function fn() {}
+      fn.toString = lodashStable.constant('fn');
+
+      var objects = [{ 'null': 1 }, { 'undefined': 2 }, { 'fn': 3 }, { '[object Object]': 4 }],
+          values = [null, undefined, fn, {}];
+
+      var actual = lodashStable.transform(objects, function(result, object, index) {
+        var key = values[index];
+        lodashStable.each([key, [key]], function(path) {
+          var propOf = _.propertyOf(object);
+          result.push(propOf(key));
+        });
+      });
+
+      assert.deepEqual(actual, [1, 1, 2, 2, 3, 3, 4, 4]);
+    });
+
+    QUnit.test('should pluck a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': 1, 'a': { 'b': 2 } },
+          propOf = _.propertyOf(object);
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        assert.strictEqual(propOf(path), 1);
+      });
+    });
+
+    QUnit.test('should return `undefined` when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        var actual = lodashStable.map(values, function(value, index) {
+          var propOf = index ? _.propertyOf(value) : _.propertyOf();
+          return propOf(path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` with deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, noop);
+
+      lodashStable.each(['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']], function(path) {
+        var actual = lodashStable.map(values, function(value, index) {
+          var propOf = index ? _.propertyOf(value) : _.propertyOf();
+          return propOf(path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should return `undefined` if parts of `path` are missing', function(assert) {
+      assert.expect(4);
+
+      var propOf = _.propertyOf({});
+
+      lodashStable.each(['a', 'a[1].b.c', ['a'], ['a', '1', 'b', 'c']], function(path) {
+        assert.strictEqual(propOf(path), undefined);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.pullAllBy');
+
+  (function() {
+    QUnit.test('should accept an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+
+      var actual = _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function(object) {
+        return object.x;
+      });
+
+      assert.deepEqual(actual, [{ 'x': 2 }]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args,
+          array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
+
+      _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [{ 'x': 1 }]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.pullAllWith');
+
+  (function() {
+    QUnit.test('should work with a `comparator` argument', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 1, 'y': 1 }, { 'x': 2, 'y': 2 }, { 'x': 3, 'y': 3 }],
+          expected = [objects[0], objects[2]],
+          actual = _.pullAllWith(objects, [{ 'x': 2, 'y': 2 }], lodashStable.isEqual);
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('pull methods');
+
+  lodashStable.each(['pull', 'pullAll', 'pullAllWith'], function(methodName) {
+    var func = _[methodName],
+        isPull = methodName == 'pull';
+
+    function pull(array, values) {
+      return isPull
+        ? func.apply(undefined, [array].concat(values))
+        : func(array, values);
+    }
+
+    QUnit.test('`_.' + methodName + '` should modify and return the array', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          actual = pull(array, [1, 3]);
+
+      assert.deepEqual(array, [2]);
+      assert.ok(actual === array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve holes in arrays', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4];
+      delete array[1];
+      delete array[3];
+
+      pull(array, [1]);
+      assert.notOk('0' in array);
+      assert.notOk('2' in array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat holes as `undefined`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      delete array[1];
+
+      pull(array, [undefined]);
+      assert.deepEqual(array, [1, 3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, NaN, 3, NaN];
+
+      pull(array, [NaN]);
+      assert.deepEqual(array, [1, 3]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.pullAt');
+
+  (function() {
+    QUnit.test('should modify the array and return removed elements', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          actual = _.pullAt(array, [0, 1]);
+
+      assert.deepEqual(array, [3]);
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('should work with unsorted indexes', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
+          actual = _.pullAt(array, [1, 3, 11, 7, 5, 9]);
+
+      assert.deepEqual(array, [1, 3, 5, 7, 9, 11]);
+      assert.deepEqual(actual, [2, 4, 12, 8, 6, 10]);
+    });
+
+    QUnit.test('should work with repeated indexes', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4],
+          actual = _.pullAt(array, [0, 2, 0, 1, 0, 2]);
+
+      assert.deepEqual(array, [4]);
+      assert.deepEqual(actual, [1, 3, 1, 2, 1, 3]);
+    });
+
+    QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
+      assert.expect(2);
+
+      var array = ['a', 'b', 'c'],
+          actual = _.pullAt(array, [2, 4, 0]);
+
+      assert.deepEqual(array, ['b']);
+      assert.deepEqual(actual, ['c', undefined, 'a']);
+    });
+
+    QUnit.test('should flatten `indexes`', function(assert) {
+      assert.expect(4);
+
+      var array = ['a', 'b', 'c'];
+      assert.deepEqual(_.pullAt(array, 2, 0), ['c', 'a']);
+      assert.deepEqual(array, ['b']);
+
+      array = ['a', 'b', 'c', 'd'];
+      assert.deepEqual(_.pullAt(array, [3, 0], 2), ['d', 'a', 'c']);
+      assert.deepEqual(array, ['b']);
+    });
+
+    QUnit.test('should return an empty array when no indexes are given', function(assert) {
+      assert.expect(4);
+
+      var array = ['a', 'b', 'c'],
+          actual = _.pullAt(array);
+
+      assert.deepEqual(array, ['a', 'b', 'c']);
+      assert.deepEqual(actual, []);
+
+      actual = _.pullAt(array, [], []);
+
+      assert.deepEqual(array, ['a', 'b', 'c']);
+      assert.deepEqual(actual, []);
+    });
+
+    QUnit.test('should work with non-index paths', function(assert) {
+      assert.expect(2);
+
+      var values = lodashStable.reject(empties, function(value) {
+        return (value === 0) || lodashStable.isArray(value);
+      }).concat(-1, 1.1);
+
+      var array = lodashStable.transform(values, function(result, value) {
+        result[value] = 1;
+      }, []);
+
+      var expected = lodashStable.map(values, alwaysOne),
+          actual = _.pullAt(array, values);
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(values, noop),
+      actual = lodashStable.at(array, values);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var props = [-0, Object(-0), 0, Object(0)];
+
+      var actual = lodashStable.map(props, function(key) {
+        var array = [-1];
+        array['-0'] = -2;
+        return _.pullAt(array, key);
+      });
+
+      assert.deepEqual(actual, [[-2], [-2], [-1], [-1]]);
+    });
+
+    QUnit.test('should work with deep paths', function(assert) {
+      assert.expect(3);
+
+      var array = [];
+      array.a = { 'b': 2 };
+
+      var actual = _.pullAt(array, 'a.b');
+
+      assert.deepEqual(actual, [2]);
+      assert.deepEqual(array.a, {});
+
+      try {
+        actual = _.pullAt(array, 'a.b.c');
+      } catch (e) {}
+
+      assert.deepEqual(actual, [undefined]);
+    });
+
+    QUnit.test('should work with a falsey `array` argument when keys are given', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.slice(),
+          expected = lodashStable.map(values, lodashStable.constant(Array(4)));
+
+      var actual = lodashStable.map(values, function(array) {
+        try {
+          return _.pullAt(array, 0, 1, 'pop', 'push');
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.random');
+
+  (function() {
+    var array = Array(1000);
+
+    QUnit.test('should return `0` or `1` when no arguments are given', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.uniq(lodashStable.map(array, function() {
+        return _.random();
+      })).sort();
+
+      assert.deepEqual(actual, [0, 1]);
+    });
+
+    QUnit.test('should support a `min` and `max` argument', function(assert) {
+      assert.expect(1);
+
+      var min = 5,
+          max = 10;
+
+      assert.ok(_.some(array, function() {
+        var result = _.random(min, max);
+        return result >= min && result <= max;
+      }));
+    });
+
+    QUnit.test('should support not providing a `max` argument', function(assert) {
+      assert.expect(1);
+
+      var min = 0,
+          max = 5;
+
+      assert.ok(_.some(array, function() {
+        var result = _.random(max);
+        return result >= min && result <= max;
+      }));
+    });
+
+    QUnit.test('should swap `min` and `max` when `min` > `max`', function(assert) {
+      assert.expect(1);
+
+      var min = 4,
+          max = 2,
+          expected = [2, 3, 4];
+
+      var actual = lodashStable.uniq(lodashStable.map(array, function() {
+        return _.random(min, max);
+      })).sort();
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should support large integer values', function(assert) {
+      assert.expect(2);
+
+      var min = Math.pow(2, 31),
+          max = Math.pow(2, 62);
+
+      assert.ok(lodashStable.every(array, function() {
+        var result = _.random(min, max);
+        return result >= min && result <= max;
+      }));
+
+      assert.ok(_.some(array, function() {
+        return _.random(MAX_INTEGER) > 0;
+      }));
+    });
+
+    QUnit.test('should coerce arguments to finite numbers', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.random('1', '1'), 1);
+      assert.strictEqual(_.random(NaN, NaN), 0);
+    });
+
+    QUnit.test('should support floats', function(assert) {
+      assert.expect(2);
+
+      var min = 1.5,
+          max = 1.6,
+          actual = _.random(min, max);
+
+      assert.ok(actual % 1);
+      assert.ok(actual >= min && actual <= max);
+    });
+
+    QUnit.test('should support providing a `floating` argument', function(assert) {
+      assert.expect(3);
+
+      var actual = _.random(true);
+      assert.ok(actual % 1 && actual >= 0 && actual <= 1);
+
+      actual = _.random(2, true);
+      assert.ok(actual % 1 && actual >= 0 && actual <= 2);
+
+      actual = _.random(2, 4, true);
+      assert.ok(actual % 1 && actual >= 2 && actual <= 4);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3],
+          expected = lodashStable.map(array, alwaysTrue),
+          randoms = lodashStable.map(array, _.random);
+
+      var actual = lodashStable.map(randoms, function(result, index) {
+        return result >= 0 && result <= array[index] && (result % 1) == 0;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('range methods');
+
+  lodashStable.each(['range', 'rangeRight'], function(methodName) {
+    var func = _[methodName],
+        isRange = methodName == 'range';
+
+    function resolve(range) {
+      return isRange ? range : range.reverse();
+    }
+
+    QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `end` is given', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(func(4), resolve([0, 1, 2, 3]));
+      assert.deepEqual(func(-4), resolve([0, -1, -2, -3]));
+    });
+
+    QUnit.test('`_.' + methodName + '` should infer the sign of `step` when only `start` and `end` are given', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(func(1, 5), resolve([1, 2, 3, 4]));
+      assert.deepEqual(func(5, 1), resolve([5, 4, 3, 2]));
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `start`, `end`, and `step` arguments', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
+      assert.deepEqual(func(5, 1, -1), resolve([5, 4, 3, 2]));
+      assert.deepEqual(func(0, 20, 5), resolve([0, 5, 10, 15]));
+    });
+
+    QUnit.test('`_.' + methodName + '` should support a `step` of `0`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(1, 4, 0), [1, 1, 1]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a `step` larger than `end`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(1, 5, 20), [1]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a negative `step`', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(func(0, -4, -1), resolve([0, -1, -2, -3]));
+      assert.deepEqual(func(21, 10, -3), resolve([21, 18, 15, 12]));
+    });
+
+    QUnit.test('`_.' + methodName + '` should support `start` of `-0`', function(assert) {
+      assert.expect(1);
+
+      var actual = func(-0, 1);
+      assert.strictEqual(1 / actual[0], -Infinity);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat falsey `start` arguments as `0`', function(assert) {
+      assert.expect(13);
+
+      lodashStable.each(falsey, function(value, index) {
+        if (index) {
+          assert.deepEqual(func(value), []);
+          assert.deepEqual(func(value, 1), [0]);
+        } else {
+          assert.deepEqual(func(), []);
+        }
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce arguments to finite numbers', function(assert) {
+      assert.expect(1);
+
+      var actual = [func('0', 1), func('1'), func(0, 1, '1'), func(NaN), func(NaN, NaN)];
+      assert.deepEqual(actual, [[0], [0], [0], [], []]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          object = { 'a': 1, 'b': 2, 'c': 3 },
+          expected = lodashStable.map([[0], [0, 1], [0, 1, 2]], resolve);
+
+      lodashStable.each([array, object], function(collection) {
+        var actual = lodashStable.map(collection, func);
+        assert.deepEqual(actual, expected);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.rearg');
+
+  (function() {
+    function fn() {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should reorder arguments provided to `func`', function(assert) {
+      assert.expect(1);
+
+      var rearged = _.rearg(fn, [2, 0, 1]);
+      assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should work with repeated indexes', function(assert) {
+      assert.expect(1);
+
+      var rearged = _.rearg(fn, [1, 1, 1]);
+      assert.deepEqual(rearged('c', 'a', 'b'), ['a', 'a', 'a']);
+    });
+
+    QUnit.test('should use `undefined` for nonexistent indexes', function(assert) {
+      assert.expect(1);
+
+      var rearged = _.rearg(fn, [1, 4]);
+      assert.deepEqual(rearged('b', 'a', 'c'), ['a', undefined, 'c']);
+    });
+
+    QUnit.test('should use `undefined` for non-index values', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.reject(empties, function(value) {
+        return (value === 0) || lodashStable.isArray(value);
+      }).concat(-1, 1.1);
+
+      var expected = lodashStable.map(values, lodashStable.constant([undefined, 'b', 'c']));
+
+      var actual = lodashStable.map(values, function(value) {
+        var rearged = _.rearg(fn, [value]);
+        return rearged('a', 'b', 'c');
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not rearrange arguments when no indexes are given', function(assert) {
+      assert.expect(2);
+
+      var rearged = _.rearg(fn);
+      assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
+
+      rearged = _.rearg(fn, [], []);
+      assert.deepEqual(rearged('a', 'b', 'c'), ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should accept multiple index arguments', function(assert) {
+      assert.expect(1);
+
+      var rearged = _.rearg(fn, 2, 0, 1);
+      assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should accept multiple arrays of indexes', function(assert) {
+      assert.expect(1);
+
+      var rearged = _.rearg(fn, [2], [0, 1]);
+      assert.deepEqual(rearged('b', 'c', 'a'), ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should work with fewer indexes than arguments', function(assert) {
+      assert.expect(1);
+
+      var rearged = _.rearg(fn, [1, 0]);
+      assert.deepEqual(rearged('b', 'a', 'c'), ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should work on functions that have been rearged', function(assert) {
+      assert.expect(1);
+
+      var rearged1 = _.rearg(fn, 2, 1, 0),
+          rearged2 = _.rearg(rearged1, 1, 0, 2);
+
+      assert.deepEqual(rearged2('b', 'c', 'a'), ['a', 'b', 'c']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.reduce');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should use the first element of a collection as the default `accumulator`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.reduce(array), 1);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
+      assert.expect(2);
+
+      var args;
+
+      _.reduce(array, function() {
+        args || (args = slice.call(arguments));
+      }, 0);
+
+      assert.deepEqual(args, [0, 1, 0, array]);
+
+      args = undefined;
+      _.reduce(array, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [1, 2, 1, array]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
+      assert.expect(2);
+
+      var args,
+          object = { 'a': 1, 'b': 2 },
+          firstKey = _.head(_.keys(object));
+
+      var expected = firstKey == 'a'
+        ? [0, 1, 'a', object]
+        : [0, 2, 'b', object];
+
+      _.reduce(object, function() {
+        args || (args = slice.call(arguments));
+      }, 0);
+
+      assert.deepEqual(args, expected);
+
+      args = undefined;
+      expected = firstKey == 'a'
+        ? [1, 2, 'b', object]
+        : [2, 1, 'a', object];
+
+      _.reduce(object, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.reduceRight');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should use the last element of a collection as the default `accumulator`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.reduceRight(array), 3);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments when iterating an array', function(assert) {
+      assert.expect(2);
+
+      var args;
+
+      _.reduceRight(array, function() {
+        args || (args = slice.call(arguments));
+      }, 0);
+
+      assert.deepEqual(args, [0, 3, 2, array]);
+
+      args = undefined;
+      _.reduceRight(array, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [3, 2, 1, array]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments when iterating an object', function(assert) {
+      assert.expect(2);
+
+      var args,
+          object = { 'a': 1, 'b': 2 },
+          isFIFO = lodashStable.keys(object)[0] == 'a';
+
+      var expected = isFIFO
+        ? [0, 2, 'b', object]
+        : [0, 1, 'a', object];
+
+      _.reduceRight(object, function() {
+        args || (args = slice.call(arguments));
+      }, 0);
+
+      assert.deepEqual(args, expected);
+
+      args = undefined;
+      expected = isFIFO
+        ? [2, 1, 'a', object]
+        : [1, 2, 'b', object];
+
+      _.reduceRight(object, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('reduce methods');
+
+  lodashStable.each(['reduce', 'reduceRight'], function(methodName) {
+    var func = _[methodName],
+        array = [1, 2, 3],
+        isReduce = methodName == 'reduce';
+
+    QUnit.test('`_.' + methodName + '` should reduce a collection to a single value', function(assert) {
+      assert.expect(1);
+
+      var actual = func(['a', 'b', 'c'], function(accumulator, value) {
+        return accumulator + value;
+      }, '');
+
+      assert.strictEqual(actual, isReduce ? 'abc' : 'cba');
+    });
+
+    QUnit.test('`_.' + methodName + '` should support empty collections without an initial `accumulator` value', function(assert) {
+      assert.expect(1);
+
+      var actual = [],
+          expected = lodashStable.map(empties, noop);
+
+      lodashStable.each(empties, function(value) {
+        try {
+          actual.push(func(value, noop));
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support empty collections with an initial `accumulator` value', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, lodashStable.constant('x'));
+
+      var actual = lodashStable.map(empties, function(value) {
+        try {
+          return func(value, noop, 'x');
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should handle an initial `accumulator` value of `undefined`', function(assert) {
+      assert.expect(1);
+
+      var actual = func([], noop, undefined);
+      assert.strictEqual(actual, undefined);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `undefined` for empty collections when no `accumulator` is given (test in IE > 9 and modern browsers)', function(assert) {
+      assert.expect(2);
+
+      var array = [],
+          object = { '0': 1, 'length': 0 };
+
+      if ('__proto__' in array) {
+        array.__proto__ = object;
+        assert.strictEqual(func(array, noop), undefined);
+      }
+      else {
+        skipAssert(assert);
+      }
+      assert.strictEqual(func(object, noop), undefined);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.strictEqual(_(array)[methodName](add), 6);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(array).chain()[methodName](add) instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.reject');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should return elements the `predicate` returns falsey for', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.reject(array, isEven), [1, 3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('filter methods');
+
+  lodashStable.each(['filter', 'reject'], function(methodName) {
+    var array = [1, 2, 3, 4],
+        func = _[methodName],
+        isFilter = methodName == 'filter',
+        objects = [{ 'a': 0 }, { 'a': 1 }];
+
+    QUnit.test('`_.' + methodName + '` should not modify the resulting value from within `predicate`', function(assert) {
+      assert.expect(1);
+
+      var actual = func([0], function(value, index, array) {
+        array[index] = 1;
+        return isFilter;
+      });
+
+      assert.deepEqual(actual, [0]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(objects, 'a'), [objects[isFilter ? 1 : 0]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(objects, objects[1]), [objects[isFilter ? 1 : 0]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not modify wrapped values', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _(array);
+
+        var actual = wrapped[methodName](function(n) {
+          return n < 3;
+        });
+
+        assert.deepEqual(actual.value(), isFilter ? [1, 2] : [3, 4]);
+
+        actual = wrapped[methodName](function(n) {
+          return n > 2;
+        });
+
+        assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            predicate = function(value) { return isFilter ? isEven(value) : !isEven(value); },
+            actual = _(array).slice(1).map(square)[methodName](predicate).value();
+
+        assert.deepEqual(actual, _[methodName](lodashStable.map(array.slice(1), square), predicate));
+
+        var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
+          return ['key' + index, index];
+        }));
+
+        actual = _(object).mapValues(square)[methodName](predicate).value();
+        assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate));
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var args,
+            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            expected = [1, 0, lodashStable.map(array.slice(1), square)];
+
+        _(array).slice(1)[methodName](function(value, index, array) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, [1, 0, array.slice(1)]);
+
+        args = undefined;
+        _(array).slice(1).map(square)[methodName](function(value, index, array) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        args = undefined;
+        _(array).slice(1).map(square)[methodName](function(value, index) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        args = undefined;
+        _(array).slice(1).map(square)[methodName](function(value) {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, [1]);
+
+        args = undefined;
+        _(array).slice(1).map(square)[methodName](function() {
+          args || (args = slice.call(arguments));
+        }).value();
+
+        assert.deepEqual(args, expected);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.remove');
+
+  (function() {
+    QUnit.test('should modify the array and return removed elements', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4];
+
+      var actual = _.remove(array, function(n) {
+        return n % 2 == 0;
+      });
+
+      assert.deepEqual(array, [1, 3]);
+      assert.deepEqual(actual, [2, 4]);
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments', function(assert) {
+      assert.expect(1);
+
+      var argsList = [],
+          array = [1, 2, 3],
+          clone = array.slice();
+
+      _.remove(array, function(n, index) {
+        var args = slice.call(arguments);
+        args[2] = args[2].slice();
+        argsList.push(args);
+        return isEven(index);
+      });
+
+      assert.deepEqual(argsList, [[1, 0, clone], [2, 1, clone], [3, 2, clone]]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
+      _.remove(objects, { 'a': 1 });
+      assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': 0, 'b': 1 }, { 'a': 1, 'b': 2 }];
+      _.remove(objects, ['a', 1]);
+      assert.deepEqual(objects, [{ 'a': 0, 'b': 1 }]);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'a': 0 }, { 'a': 1 }];
+      _.remove(objects, 'a');
+      assert.deepEqual(objects, [{ 'a': 0 }]);
+    });
+
+    QUnit.test('should preserve holes in arrays', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3, 4];
+      delete array[1];
+      delete array[3];
+
+      _.remove(array, function(n) {
+        return n === 1;
+      });
+
+      assert.notOk('0' in array);
+      assert.notOk('2' in array);
+    });
+
+    QUnit.test('should treat holes as `undefined`', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+      delete array[1];
+
+      _.remove(array, function(n) {
+        return n == null;
+      });
+
+      assert.deepEqual(array, [1, 3]);
+    });
+
+    QUnit.test('should not mutate the array until all elements to remove are determined', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3];
+
+      _.remove(array, function(n, index) {
+        return isEven(index);
+      });
+
+      assert.deepEqual(array, [2]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.repeat');
+
+  (function() {
+    var string = 'abc';
+
+    QUnit.test('should repeat a string `n` times', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.repeat('*', 3), '***');
+      assert.strictEqual(_.repeat(string, 2), 'abcabc');
+    });
+
+    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? string : '';
+      });
+
+      var actual = lodashStable.map(falsey, function(n, index) {
+        return index ? _.repeat(string, n) : _.repeat(string);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an empty string if `n` is <= `0`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.repeat(string, 0), '');
+      assert.strictEqual(_.repeat(string, -2), '');
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.repeat(string, '2'), 'abcabc');
+      assert.strictEqual(_.repeat(string, 2.6), 'abcabc');
+      assert.strictEqual(_.repeat('*', { 'valueOf': alwaysThree }), '***');
+    });
+
+    QUnit.test('should coerce `string` to a string', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.repeat(Object(string), 2), 'abcabc');
+      assert.strictEqual(_.repeat({ 'toString': lodashStable.constant('*') }, 3), '***');
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(['a', 'b', 'c'], _.repeat);
+      assert.deepEqual(actual, ['a', 'b', 'c']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.replace');
+
+  (function() {
+    QUnit.test('should replace the matched pattern', function(assert) {
+      assert.expect(2);
+
+      var string = 'abcde';
+      assert.strictEqual(_.replace(string, 'de', '123'), 'abc123');
+      assert.strictEqual(_.replace(string, /[bd]/g, '-'), 'a-c-e');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.result');
+
+  (function() {
+    var object = { 'a': 1, 'b': alwaysB };
+
+    QUnit.test('should invoke function values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.result(object, 'b'), 'b');
+    });
+
+    QUnit.test('should invoke default function values', function(assert) {
+      assert.expect(1);
+
+      var actual = _.result(object, 'c', object.b);
+      assert.strictEqual(actual, 'b');
+    });
+
+    QUnit.test('should invoke nested function values', function(assert) {
+      assert.expect(2);
+
+      var value = { 'a': lodashStable.constant({ 'b': alwaysB }) };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(_.result(value, path), 'b');
+      });
+    });
+
+    QUnit.test('should invoke deep property methods with the correct `this` binding', function(assert) {
+      assert.expect(2);
+
+      var value = { 'a': { 'b': function() { return this.c; }, 'c': 1 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(_.result(value, path), 1);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.get and lodash.result');
+
+  lodashStable.each(['get', 'result'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should get string keyed property values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1 };
+
+      lodashStable.each(['a', ['a']], function(path) {
+        assert.strictEqual(func(object, path), 1);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var object = { '-0': 'a', '0': 'b' },
+          props = [-0, Object(-0), 0, Object(0)];
+
+      var actual = lodashStable.map(props, function(key) {
+        return func(object, key);
+      });
+
+      assert.deepEqual(actual, ['a', 'a', 'b', 'b']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should get symbol keyed property values', function(assert) {
+      assert.expect(1);
+
+      if (Symbol) {
+        var object = {};
+        object[symbol] = 1;
+
+        assert.strictEqual(func(object, symbol), 1);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should get deep property values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(func(object, path), 2);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should get a key over a path', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a.b': 1, 'a': { 'b': 2 } };
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        assert.strictEqual(func(object, path), 1);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a,b,c': 3, 'a': { 'b': { 'c': 4 } } };
+      assert.strictEqual(func(object, ['a', 'b', 'c']), 4);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1 };
+      assert.strictEqual(func(object, 'a[]'), 1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([['', ''], [[], ['']]], function(pair) {
+        assert.strictEqual(func({}, pair[0]), undefined);
+        assert.strictEqual(func({ '': 3 }, pair[1]), 3);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
+
+      var paths = [
+        'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
+        ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
+      ];
+
+      lodashStable.each(paths, function(path) {
+        assert.strictEqual(func(object, path), 8);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `undefined` when `object` is nullish', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['constructor', ['constructor']], function(path) {
+        assert.strictEqual(func(null, path), undefined);
+        assert.strictEqual(func(undefined, path), undefined);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `undefined` with deep paths when `object` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [null, undefined],
+          expected = lodashStable.map(values, noop),
+          paths = ['constructor.prototype.valueOf', ['constructor', 'prototype', 'valueOf']];
+
+      lodashStable.each(paths, function(path) {
+        var actual = lodashStable.map(values, function(value) {
+          return func(value, path);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `undefined` if parts of `path` are missing', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': [, null] };
+
+      lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
+        assert.strictEqual(func(object, path), undefined);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should be able to return `null` values', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { 'b': null } };
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        assert.strictEqual(func(object, path), null);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
+      assert.expect(2);
+
+      var paths = ['a.b', ['a', 'b']];
+
+      lodashStable.each(paths, function(path) {
+        numberProto.a = { 'b': 2 };
+        assert.strictEqual(func(0, path), 2);
+        delete numberProto.a;
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should return the default value for `undefined` values', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': {} },
+          values = empties.concat(true, new Date, 1, /x/, 'a');
+
+      var expected = lodashStable.transform(values, function(result, value) {
+        result.push(value, value, value, value);
+      });
+
+      var actual = lodashStable.transform(values, function(result, value) {
+        lodashStable.each(['a.b', ['a', 'b']], function(path) {
+          result.push(
+            func(object, path, value),
+            func(null, path, value)
+          );
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return the default value when `path` is empty', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func({}, [], 'a'), 'a');
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.rest');
+
+  (function() {
+    function fn(a, b, c) {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should apply a rest parameter to `func`', function(assert) {
+      assert.expect(1);
+
+      var rest = _.rest(fn);
+      assert.deepEqual(rest(1, 2, 3, 4), [1, 2, [3, 4]]);
+    });
+
+    QUnit.test('should work with `start`', function(assert) {
+      assert.expect(1);
+
+      var rest = _.rest(fn, 1);
+      assert.deepEqual(rest(1, 2, 3, 4), [1, [2, 3, 4]]);
+    });
+
+    QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
+      assert.expect(1);
+
+      var values = [-1, NaN, 'a'],
+          expected = lodashStable.map(values, lodashStable.constant([[1, 2, 3, 4]]));
+
+      var actual = lodashStable.map(values, function(value) {
+        var rest = _.rest(fn, value);
+        return rest(1, 2, 3, 4);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce `start` to an integer', function(assert) {
+      assert.expect(1);
+
+      var rest = _.rest(fn, 1.6);
+      assert.deepEqual(rest(1, 2, 3), [1, [2, 3]]);
+    });
+
+    QUnit.test('should use an empty array when `start` is not reached', function(assert) {
+      assert.expect(1);
+
+      var rest = _.rest(fn);
+      assert.deepEqual(rest(1), [1, undefined, []]);
+    });
+
+    QUnit.test('should work on functions with more than three parameters', function(assert) {
+      assert.expect(1);
+
+      var rest = _.rest(function(a, b, c, d) {
+        return slice.call(arguments);
+      });
+
+      assert.deepEqual(rest(1, 2, 3, 4, 5), [1, 2, 3, [4, 5]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.reverse');
+
+  (function() {
+    var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null),
+        smallArray = [0, 1, 2, null];
+
+    QUnit.test('should reverse `array`', function(assert) {
+      assert.expect(2);
+
+      var array = [1, 2, 3],
+          actual = _.reverse(array);
+
+      assert.deepEqual(array, [3, 2, 1]);
+      assert.strictEqual(actual, array);
+    });
+
+    QUnit.test('should return the wrapped reversed `array`', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        lodashStable.times(2, function(index) {
+          var array = (index ? largeArray : smallArray).slice(),
+              clone = array.slice(),
+              wrapped = _(array).reverse(),
+              actual = wrapped.value();
+
+          assert.ok(wrapped instanceof _);
+          assert.strictEqual(actual, array);
+          assert.deepEqual(actual, clone.slice().reverse());
+        });
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        lodashStable.times(2, function(index) {
+          var array = (index ? largeArray : smallArray).slice(),
+              expected = array.slice(),
+              actual = _(array).slice(1).reverse().value();
+
+          assert.deepEqual(actual, expected.slice(1).reverse());
+          assert.deepEqual(array, expected);
+        });
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should be lazy when in a lazy sequence', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var spy = {
+          'toString': function() {
+            throw new Error('spy was revealed');
+          }
+        };
+
+        var array = largeArray.concat(spy),
+            expected = array.slice();
+
+        try {
+          var wrapped = _(array).slice(1).map(String).reverse(),
+              actual = wrapped.last();
+        } catch (e) {}
+
+        assert.ok(wrapped instanceof _);
+        assert.strictEqual(actual, '1');
+        assert.deepEqual(array, expected);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should work in a hybrid sequence', function(assert) {
+      assert.expect(8);
+
+      if (!isNpm) {
+        lodashStable.times(2, function(index) {
+          var clone = (index ? largeArray : smallArray).slice();
+
+          lodashStable.each(['map', 'filter'], function(methodName) {
+            var array = clone.slice(),
+                expected = clone.slice(1, -1).reverse(),
+                actual = _(array)[methodName](identity).thru(_.compact).reverse().value();
+
+            assert.deepEqual(actual, expected);
+
+            array = clone.slice();
+            actual = _(array).thru(_.compact)[methodName](identity).pull(1).push(3).reverse().value();
+
+            assert.deepEqual(actual, [3].concat(expected.slice(0, -1)));
+          });
+        });
+      }
+      else {
+        skipAssert(assert, 8);
+      }
+    });
+
+    QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        lodashStable.times(2, function(index) {
+          var array = (index ? largeArray : smallArray).slice(),
+              expected = array.slice().reverse(),
+              wrapped = _(array).chain().reverse().head();
+
+          assert.ok(wrapped instanceof _);
+          assert.strictEqual(wrapped.value(), _.head(expected));
+          assert.deepEqual(array, expected);
+        });
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('round methods');
+
+  lodashStable.each(['ceil', 'floor', 'round'], function(methodName) {
+    var func = _[methodName],
+        isCeil = methodName == 'ceil',
+        isFloor = methodName == 'floor';
+
+    QUnit.test('`_.' + methodName + '` should return a rounded number without a precision', function(assert) {
+      assert.expect(1);
+
+      var actual = func(4.006);
+      assert.strictEqual(actual, isCeil ? 5 : 4);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a precision of `0`', function(assert) {
+      assert.expect(1);
+
+      var actual = func(4.006, 0);
+      assert.strictEqual(actual, isCeil ? 5 : 4);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a positive precision', function(assert) {
+      assert.expect(2);
+
+      var actual = func(4.016, 2);
+      assert.strictEqual(actual, isFloor ? 4.01 : 4.02);
+
+      actual = func(4.1, 2);
+      assert.strictEqual(actual, 4.1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a negative precision', function(assert) {
+      assert.expect(1);
+
+      var actual = func(4160, -2);
+      assert.strictEqual(actual, isFloor ? 4100 : 4200);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `precision` to an integer', function(assert) {
+      assert.expect(3);
+
+      var actual = func(4.006, NaN);
+      assert.strictEqual(actual, isCeil ? 5 : 4);
+
+      var expected = isFloor ? 4.01 : 4.02;
+
+      actual = func(4.016, 2.6);
+      assert.strictEqual(actual, expected);
+
+      actual = func(4.016, '+2');
+      assert.strictEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with exponential notation and `precision`', function(assert) {
+      assert.expect(3);
+
+      var actual = func(5e1, 2);
+      assert.deepEqual(actual, 50);
+
+      actual = func('5e', 1);
+      assert.deepEqual(actual, NaN);
+
+      actual = func('5e1e1', 1);
+      assert.deepEqual(actual, NaN);
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var values = [[0], [-0], ['0'], ['-0'], [0, 1], [-0, 1], ['0', 1], ['-0', 1]],
+          expected = [Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity, Infinity, -Infinity];
+
+      var actual = lodashStable.map(values, function(args) {
+        return 1 / func.apply(undefined, args);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.runInContext');
+
+  (function() {
+    QUnit.test('should not require a fully populated `context` object', function(assert) {
+      assert.expect(1);
+
+      if (!isModularize) {
+        var lodash = _.runInContext({
+          'setTimeout': function(callback) {
+            callback();
+          }
+        });
+
+        var pass = false;
+        lodash.delay(function() { pass = true; }, 32);
+        assert.ok(pass);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should use a zeroed `_.uniqueId` counter', function(assert) {
+      assert.expect(3);
+
+      if (!isModularize) {
+        lodashStable.times(2, _.uniqueId);
+
+        var oldId = Number(_.uniqueId()),
+            lodash = _.runInContext();
+
+        assert.ok(_.uniqueId() > oldId);
+
+        var id = lodash.uniqueId();
+        assert.strictEqual(id, '1');
+        assert.ok(id < oldId);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.sample');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should return a random element', function(assert) {
+      assert.expect(1);
+
+      var actual = _.sample(array);
+      assert.ok(lodashStable.includes(array, actual));
+    });
+
+    QUnit.test('should return `undefined` when sampling empty collections', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, noop);
+
+      var actual = lodashStable.transform(empties, function(result, value) {
+        try {
+          result.push(_.sample(value));
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should sample an object', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          actual = _.sample(object);
+
+      assert.ok(lodashStable.includes(array, actual));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.sampleSize');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should return an array of random elements', function(assert) {
+      assert.expect(2);
+
+      var actual = _.sampleSize(array, 2);
+
+      assert.strictEqual(actual.length, 2);
+      assert.deepEqual(lodashStable.difference(actual, array), []);
+    });
+
+    QUnit.test('should contain elements of the collection', function(assert) {
+      assert.expect(1);
+
+      var actual = _.sampleSize(array, array.length).sort();
+
+      assert.deepEqual(actual, array);
+    });
+
+    QUnit.test('should treat falsey `size` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? ['a'] : [];
+      });
+
+      var actual = lodashStable.map(falsey, function(size, index) {
+        return index ? _.sampleSize(['a'], size) : _.sampleSize(['a']);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an empty array when `n` < `1` or `NaN`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([0, -1, -Infinity], function(n) {
+        assert.deepEqual(_.sampleSize(array, n), []);
+      });
+    });
+
+    QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
+        var actual = _.sampleSize(array, n).sort();
+        assert.deepEqual(actual, array);
+      });
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(1);
+
+      var actual = _.sampleSize(array, 1.6);
+      assert.strictEqual(actual.length, 1);
+    });
+
+    QUnit.test('should return an empty array for empty collections', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, alwaysEmptyArray);
+
+      var actual = lodashStable.transform(empties, function(result, value) {
+        try {
+          result.push(_.sampleSize(value, 1));
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should sample an object', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': 1, 'b': 2, 'c': 3 },
+          actual = _.sampleSize(object, 2);
+
+      assert.strictEqual(actual.length, 2);
+      assert.deepEqual(lodashStable.difference(actual, lodashStable.values(object)), []);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map([['a']], _.sampleSize);
+      assert.deepEqual(actual, [['a']]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.setWith');
+
+  (function() {
+    QUnit.test('should work with a `customizer` callback', function(assert) {
+      assert.expect(1);
+
+      var actual = _.setWith({ '0': {} }, '[0][1][2]', 3, function(value) {
+        return lodashStable.isObject(value) ? undefined : {};
+      });
+
+      assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
+    });
+
+    QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.setWith({}, 'a[0].b.c', 4, noop);
+      assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('set methods');
+
+  lodashStable.each(['update', 'updateWith', 'set', 'setWith'], function(methodName) {
+    var func = _[methodName],
+        isUpdate = methodName == 'update' || methodName == 'updateWith';
+
+    var oldValue = 1,
+        value = 2,
+        updater = isUpdate ? lodashStable.constant(value) : value;
+
+    QUnit.test('`_.' + methodName + '` should set property values', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var object = { 'a': oldValue },
+            actual = func(object, path, updater);
+
+        assert.strictEqual(actual, object);
+        assert.strictEqual(object.a, value);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var props = [-0, Object(-0), 0, Object(0)],
+          expected = lodashStable.map(props, lodashStable.constant(value));
+
+      var actual = lodashStable.map(props, function(key) {
+        var object = { '-0': 'a', '0': 'b' };
+        func(object, key, updater);
+        return object[lodashStable.toString(key)];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should unset symbol keyed property values', function(assert) {
+      assert.expect(2);
+
+      if (Symbol) {
+        var object = {};
+        object[symbol] = 1;
+
+        assert.strictEqual(_.unset(object, symbol), true);
+        assert.notOk(symbol in object);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should set deep property values', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var object = { 'a': { 'b': oldValue } },
+            actual = func(object, path, updater);
+
+        assert.strictEqual(actual, object);
+        assert.strictEqual(object.a.b, value);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should set a key over a path', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a.b', ['a.b']], function(path) {
+        var object = { 'a.b': oldValue },
+            actual = func(object, path, updater);
+
+        assert.strictEqual(actual, object);
+        assert.deepEqual(object, { 'a.b': value });
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not coerce array paths to strings', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a,b,c': 1, 'a': { 'b': { 'c': 1 } } };
+
+      func(object, ['a', 'b', 'c'], updater);
+      assert.strictEqual(object.a.b.c, value);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore empty brackets', function(assert) {
+      assert.expect(1);
+
+      var object = {};
+
+      func(object, 'a[]', updater);
+      assert.deepEqual(object, { 'a': value });
+    });
+
+    QUnit.test('`_.' + methodName + '` should handle empty paths', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([['', ''], [[], ['']]], function(pair, index) {
+        var object = {};
+
+        func(object, pair[0], updater);
+        assert.deepEqual(object, index ? {} : { '': value });
+
+        func(object, pair[1], updater);
+        assert.deepEqual(object, { '': value });
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should handle complex paths', function(assert) {
+      assert.expect(2);
+
+      var object = { 'a': { '1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': oldValue } } } } } } } };
+
+      var paths = [
+        'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
+        ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
+      ];
+
+      lodashStable.each(paths, function(path) {
+        func(object, path, updater);
+        assert.strictEqual(object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g, value);
+        object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f.g = oldValue;
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should create parts of `path` that are missing', function(assert) {
+      assert.expect(6);
+
+      var object = {};
+
+      lodashStable.each(['a[1].b.c', ['a', '1', 'b', 'c']], function(path) {
+        var actual = func(object, path, updater);
+
+        assert.strictEqual(actual, object);
+        assert.deepEqual(actual, { 'a': [undefined, { 'b': { 'c': value } }] });
+        assert.notOk('0' in object.a);
+
+        delete object.a;
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not error when `object` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [null, undefined],
+          expected = [[null, null], [undefined, undefined]];
+
+      var actual = lodashStable.map(values, function(value) {
+        try {
+          return [func(value, 'a.b', updater), func(value, ['a', 'b'], updater)];
+        } catch (e) {
+          return e.message;
+        }
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should follow `path` over non-plain objects', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': '' },
+          paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
+
+      lodashStable.each(paths, function(path) {
+        func(0, path, updater);
+        assert.strictEqual(0..a, value);
+        delete numberProto.a;
+      });
+
+      lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
+        func(object, path, updater);
+        assert.strictEqual(stringProto.replace.b, value);
+        delete stringProto.replace.b;
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not error on paths over primitives in strict mode', function(assert) {
+      'use strict';
+
+      assert.expect(2);
+
+      lodashStable.each(['a', 'a.a.a'], function(path) {
+        numberProto.a = oldValue;
+        try {
+          func(0, path, updater);
+          assert.strictEqual(0..a, oldValue);
+        } catch (e) {
+          assert.ok(false, e.message);
+        }
+      });
+
+      delete numberProto.a;
+    });
+
+    QUnit.test('`_.' + methodName + '` should not create an array for missing non-index property names that start with numbers', function(assert) {
+      assert.expect(1);
+
+      var object = {};
+
+      func(object, ['1a', '2b', '3c'], updater);
+      assert.deepEqual(object, { '1a': { '2b': { '3c': value } } });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not assign values that are the same as their destinations', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a', ['a'], { 'a': 1 }, NaN], function(value) {
+        if (defineProperty) {
+          var object = {},
+              pass = true,
+              updater = isUpdate ? lodashStable.constant(value) : value;
+
+          defineProperty(object, 'a', {
+            'enumerable': true,
+            'configurable': true,
+            'get': lodashStable.constant(value),
+            'set': function() { pass = false; }
+          });
+
+          func(object, 'a', updater);
+          assert.ok(pass);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.shuffle');
+
+  (function() {
+    var array = [1, 2, 3],
+        object = { 'a': 1, 'b': 2, 'c': 3 };
+
+    QUnit.test('should return a new array', function(assert) {
+      assert.expect(1);
+
+      assert.notStrictEqual(_.shuffle(array), array);
+    });
+
+    QUnit.test('should contain the same elements after a collection is shuffled', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.shuffle(array).sort(), array);
+      assert.deepEqual(_.shuffle(object).sort(), array);
+    });
+
+    QUnit.test('should shuffle small collections', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.times(1000, function(assert) {
+        return _.shuffle([1, 2]);
+      });
+
+      assert.deepEqual(lodashStable.sortBy(lodashStable.uniqBy(actual, String), '0'), [[1, 2], [2, 1]]);
+    });
+
+    QUnit.test('should treat number values for `collection` as empty', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.shuffle(1), []);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.size');
+
+  (function() {
+    var args = arguments,
+        array = [1, 2, 3];
+
+    QUnit.test('should return the number of own enumerable string keyed properties of an object', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.size({ 'one': 1, 'two': 2, 'three': 3 }), 3);
+    });
+
+    QUnit.test('should return the length of an array', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.size(array), 3);
+    });
+
+    QUnit.test('should accept a falsey `object` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysZero);
+
+      var actual = lodashStable.map(falsey, function(object, index) {
+        try {
+          return index ? _.size(object) : _.size();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.size(args), 3);
+    });
+
+    QUnit.test('should work with jQuery/MooTools DOM query collections', function(assert) {
+      assert.expect(1);
+
+      function Foo(elements) {
+        push.apply(this, elements);
+      }
+      Foo.prototype = { 'length': 0, 'splice': arrayProto.splice };
+
+      assert.strictEqual(_.size(new Foo(array)), 3);
+    });
+
+    QUnit.test('should work with maps', function(assert) {
+      assert.expect(2);
+
+      if (Map) {
+        lodashStable.each([new Map, realm.map], function(map) {
+          map.set('a', 1);
+          map.set('b', 2);
+          assert.strictEqual(_.size(map), 2);
+          map.clear();
+        });
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should work with sets', function(assert) {
+      assert.expect(2);
+
+      if (Set) {
+        lodashStable.each([new Set, realm.set], function(set) {
+          set.add(1);
+          set.add(2);
+          assert.strictEqual(_.size(set), 2);
+          set.clear();
+        });
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should not treat objects with negative lengths as array-like', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.size({ 'length': -1 }), 1);
+    });
+
+    QUnit.test('should not treat objects with lengths larger than `MAX_SAFE_INTEGER` as array-like', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.size({ 'length': MAX_SAFE_INTEGER + 1 }), 1);
+    });
+
+    QUnit.test('should not treat objects with non-number lengths as array-like', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.size({ 'length': '0' }), 1);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.slice');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should use a default `start` of `0` and a default `end` of `array.length`', function(assert) {
+      assert.expect(2);
+
+      var actual = _.slice(array);
+      assert.deepEqual(actual, array);
+      assert.notStrictEqual(actual, array);
+    });
+
+    QUnit.test('should work with a positive `start`', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.slice(array, 1), [2, 3]);
+      assert.deepEqual(_.slice(array, 1, 3), [2, 3]);
+    });
+
+    QUnit.test('should work with a `start` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(start) {
+        assert.deepEqual(_.slice(array, start), []);
+      });
+    });
+
+    QUnit.test('should treat falsey `start` values as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, lodashStable.constant(array));
+
+      var actual = lodashStable.map(falsey, function(start) {
+        return _.slice(array, start);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with a negative `start`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.slice(array, -1), [3]);
+    });
+
+    QUnit.test('should work with a negative `start` <= negative `array.length`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([-3, -4, -Infinity], function(start) {
+        assert.deepEqual(_.slice(array, start), array);
+      });
+    });
+
+    QUnit.test('should work with `start` >= `end`', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([2, 3], function(start) {
+        assert.deepEqual(_.slice(array, start, 2), []);
+      });
+    });
+
+    QUnit.test('should work with a positive `end`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.slice(array, 0, 1), [1]);
+    });
+
+    QUnit.test('should work with a `end` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(end) {
+        assert.deepEqual(_.slice(array, 0, end), array);
+      });
+    });
+
+    QUnit.test('should treat falsey `end` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? array : [];
+      });
+
+      var actual = lodashStable.map(falsey, function(end, index) {
+        return index ? _.slice(array, 0, end) : _.slice(array, 0);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with a negative `end`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.slice(array, 0, -1), [1, 2]);
+    });
+
+    QUnit.test('should work with a negative `end` <= negative `array.length`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([-3, -4, -Infinity], function(end) {
+        assert.deepEqual(_.slice(array, 0, end), []);
+      });
+    });
+
+    QUnit.test('should coerce `start` and `end` to integers', function(assert) {
+      assert.expect(1);
+
+      var positions = [[0.1, 1.6], ['0', 1], [0, '1'], ['1'], [NaN, 1], [1, NaN]];
+
+      var actual = lodashStable.map(positions, function(pos) {
+        return _.slice.apply(_, [array].concat(pos));
+      });
+
+      assert.deepEqual(actual, [[1], [1], [1], [2, 3], [1], []]);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(2);
+
+      var array = [[1], [2, 3]],
+          actual = lodashStable.map(array, _.slice);
+
+      assert.deepEqual(actual, array);
+      assert.notStrictEqual(actual, array);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(38);
+
+      if (!isNpm) {
+        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
+            length = array.length,
+            wrapped = _(array);
+
+        lodashStable.each(['map', 'filter'], function(methodName) {
+          assert.deepEqual(wrapped[methodName]().slice(0, -1).value(), array.slice(0, -1));
+          assert.deepEqual(wrapped[methodName]().slice(1).value(), array.slice(1));
+          assert.deepEqual(wrapped[methodName]().slice(1, 3).value(), array.slice(1, 3));
+          assert.deepEqual(wrapped[methodName]().slice(-1).value(), array.slice(-1));
+
+          assert.deepEqual(wrapped[methodName]().slice(length).value(), array.slice(length));
+          assert.deepEqual(wrapped[methodName]().slice(3, 2).value(), array.slice(3, 2));
+          assert.deepEqual(wrapped[methodName]().slice(0, -length).value(), array.slice(0, -length));
+          assert.deepEqual(wrapped[methodName]().slice(0, null).value(), array.slice(0, null));
+
+          assert.deepEqual(wrapped[methodName]().slice(0, length).value(), array.slice(0, length));
+          assert.deepEqual(wrapped[methodName]().slice(-length).value(), array.slice(-length));
+          assert.deepEqual(wrapped[methodName]().slice(null).value(), array.slice(null));
+
+          assert.deepEqual(wrapped[methodName]().slice(0, 1).value(), array.slice(0, 1));
+          assert.deepEqual(wrapped[methodName]().slice(NaN, '1').value(), array.slice(NaN, '1'));
+
+          assert.deepEqual(wrapped[methodName]().slice(0.1, 1.1).value(), array.slice(0.1, 1.1));
+          assert.deepEqual(wrapped[methodName]().slice('0', 1).value(), array.slice('0', 1));
+          assert.deepEqual(wrapped[methodName]().slice(0, '1').value(), array.slice(0, '1'));
+          assert.deepEqual(wrapped[methodName]().slice('1').value(), array.slice('1'));
+          assert.deepEqual(wrapped[methodName]().slice(NaN, 1).value(), array.slice(NaN, 1));
+          assert.deepEqual(wrapped[methodName]().slice(1, NaN).value(), array.slice(1, NaN));
+        });
+      }
+      else {
+        skipAssert(assert, 38);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.some');
+
+  (function() {
+    QUnit.test('should return `true` if `predicate` returns truthy for any element', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.some([false, 1, ''], identity), true);
+      assert.strictEqual(_.some([null, 'a', 0], identity), true);
+    });
+
+    QUnit.test('should return `false` for empty collections', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, alwaysFalse);
+
+      var actual = lodashStable.map(empties, function(value) {
+        try {
+          return _.some(value, identity);
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return `true` as soon as `predicate` returns truthy', function(assert) {
+      assert.expect(2);
+
+      var count = 0;
+
+      assert.strictEqual(_.some([null, true, null], function(value) {
+        count++;
+        return value;
+      }), true);
+
+      assert.strictEqual(count, 2);
+    });
+
+    QUnit.test('should return `false` if `predicate` returns falsey for all elements', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.some([false, false, false], identity), false);
+      assert.strictEqual(_.some([null, 0, ''], identity), false);
+    });
+
+    QUnit.test('should use `_.identity` when `predicate` is nullish', function(assert) {
+      assert.expect(2);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var array = [0, 0];
+        return index ? _.some(array, value) : _.some(array);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(values, alwaysTrue);
+      actual = lodashStable.map(values, function(value, index) {
+        var array = [0, 1];
+        return index ? _.some(array, value) : _.some(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var objects = [{ 'a': 0, 'b': 0 }, { 'a': 0, 'b': 1 }];
+      assert.strictEqual(_.some(objects, 'a'), false);
+      assert.strictEqual(_.some(objects, 'b'), true);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(2);
+
+      var objects = [{ 'a': 0, 'b': 0 }, { 'a': 1, 'b': 1}];
+      assert.strictEqual(_.some(objects, { 'a': 0 }), true);
+      assert.strictEqual(_.some(objects, { 'b': 2 }), false);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map([[1]], _.some);
+      assert.deepEqual(actual, [true]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.sortBy');
+
+  (function() {
+    var objects = [
+      { 'a': 'x', 'b': 3 },
+      { 'a': 'y', 'b': 4 },
+      { 'a': 'x', 'b': 1 },
+      { 'a': 'y', 'b': 2 }
+    ];
+
+    QUnit.test('should sort in ascending order by `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(_.sortBy(objects, function(object) {
+        return object.b;
+      }), 'b');
+
+      assert.deepEqual(actual, [1, 2, 3, 4]);
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var array = [3, 2, 1],
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.sortBy(array, value) : _.sortBy(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(_.sortBy(objects.concat(undefined), 'b'), 'b');
+      assert.deepEqual(actual, [1, 2, 3, 4, undefined]);
+    });
+
+    QUnit.test('should work with an object for `collection`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.sortBy({ 'a': 1, 'b': 2, 'c': 3 }, Math.sin);
+      assert.deepEqual(actual, [3, 1, 2]);
+    });
+
+    QUnit.test('should move symbol, `null`, `undefined`, and `NaN` values to the end', function(assert) {
+      assert.expect(2);
+
+      var symbol1 = Symbol ? Symbol('a') : null,
+          symbol2 = Symbol ? Symbol('b') : null,
+          array = [NaN, undefined, null, 4, symbol1, null, 1, symbol2, undefined, 3, NaN, 2],
+          expected = [1, 2, 3, 4, symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
+
+      assert.deepEqual(_.sortBy(array), expected);
+
+      array = [NaN, undefined, symbol1, null, 'd', null, 'a', symbol2, undefined, 'c', NaN, 'b'];
+      expected = ['a', 'b', 'c', 'd', symbol1, symbol2, null, null, undefined, undefined, NaN, NaN];
+
+      assert.deepEqual(_.sortBy(array), expected);
+    });
+
+    QUnit.test('should treat number values for `collection` as empty', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.sortBy(1), []);
+    });
+
+    QUnit.test('should coerce arrays returned from `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.sortBy(objects, function(object) {
+        var result = [object.a, object.b];
+        result.toString = function() { return String(this[0]); };
+        return result;
+      });
+
+      assert.deepEqual(actual, [objects[0], objects[2], objects[1], objects[3]]);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map([[2, 1, 3], [3, 2, 1]], _.sortBy);
+      assert.deepEqual(actual, [[1, 2, 3], [1, 2, 3]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('sortBy methods');
+
+  lodashStable.each(['orderBy', 'sortBy'], function(methodName) {
+    var func = _[methodName];
+
+    function Pair(a, b, c) {
+      this.a = a;
+      this.b = b;
+      this.c = c;
+    }
+
+    var objects = [
+      { 'a': 'x', 'b': 3 },
+      { 'a': 'y', 'b': 4 },
+      { 'a': 'x', 'b': 1 },
+      { 'a': 'y', 'b': 2 }
+    ];
+
+    var stableArray = [
+      new Pair(1, 1, 1), new Pair(1, 2, 1),
+      new Pair(1, 1, 1), new Pair(1, 2, 1),
+      new Pair(1, 3, 1), new Pair(1, 4, 1),
+      new Pair(1, 5, 1), new Pair(1, 6, 1),
+      new Pair(2, 1, 2), new Pair(2, 2, 2),
+      new Pair(2, 3, 2), new Pair(2, 4, 2),
+      new Pair(2, 5, 2), new Pair(2, 6, 2),
+      new Pair(undefined, 1, 1), new Pair(undefined, 2, 1),
+      new Pair(undefined, 3, 1), new Pair(undefined, 4, 1),
+      new Pair(undefined, 5, 1), new Pair(undefined, 6, 1)
+    ];
+
+    var stableObject = lodashStable.zipObject('abcdefghijklmnopqrst'.split(''), stableArray);
+
+    QUnit.test('`_.' + methodName + '` should sort multiple properties in ascending order', function(assert) {
+      assert.expect(1);
+
+      var actual = func(objects, ['a', 'b']);
+      assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support iteratees', function(assert) {
+      assert.expect(1);
+
+      var actual = func(objects, ['a', function(object) { return object.b; }]);
+      assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should perform a stable sort (test in IE > 8 and V8)', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([stableArray, stableObject], function(value, index) {
+        var actual = func(value, ['a', 'c']);
+        assert.deepEqual(actual, stableArray, index ? 'object' : 'array');
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should not error on nullish elements', function(assert) {
+      assert.expect(1);
+
+      try {
+        var actual = func(objects.concat(null, undefined), ['a', 'b']);
+      } catch (e) {}
+
+      assert.deepEqual(actual, [objects[2], objects[0], objects[3], objects[1], null, undefined]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.reduce`', function(assert) {
+      assert.expect(3);
+
+      var objects = [
+        { 'a': 'x', '0': 3 },
+        { 'a': 'y', '0': 4 },
+        { 'a': 'x', '0': 1 },
+        { 'a': 'y', '0': 2 }
+      ];
+
+      var funcs = [func, lodashStable.partialRight(func, 'bogus')];
+
+      lodashStable.each(['a', 0, [0]], function(props, index) {
+        var expected = lodashStable.map(funcs, lodashStable.constant(
+          index
+            ? [objects[2], objects[3], objects[0], objects[1]]
+            : [objects[0], objects[2], objects[1], objects[3]]
+        ));
+
+        var actual = lodashStable.map(funcs, function(func) {
+          return lodashStable.reduce([props], func, objects);
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('sortedIndex methods');
+
+  lodashStable.each(['sortedIndex', 'sortedLastIndex'], function(methodName) {
+    var func = _[methodName],
+        isSortedIndex = methodName == 'sortedIndex';
+
+    QUnit.test('`_.' + methodName + '` should return the insert index', function(assert) {
+      assert.expect(1);
+
+      var array = [30, 50],
+          values = [30, 40, 50],
+          expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(array, value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with an array of strings', function(assert) {
+      assert.expect(1);
+
+      var array = ['a', 'c'],
+          values = ['a', 'b', 'c'],
+          expected = isSortedIndex ? [0, 1, 1] : [1, 1, 2];
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(array, value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should accept a falsey `array` argument and a `value`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, lodashStable.constant([0, 0, 0]));
+
+      var actual = lodashStable.map(falsey, function(array) {
+        return [func(array, 1), func(array, undefined), func(array, NaN)];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should align with `_.sortBy`', function(assert) {
+      assert.expect(12);
+
+      var symbol1 = Symbol ? Symbol('a') : null,
+          symbol2 = Symbol ? Symbol('b') : null,
+          expected = [1, '2', {}, symbol1, symbol2, null, undefined, NaN, NaN];
+
+      lodashStable.each([
+        [NaN, symbol1, null, 1, '2', {}, symbol2, NaN, undefined],
+        ['2', null, 1, symbol1, NaN, {}, NaN, symbol2, undefined]
+      ], function(array) {
+        assert.deepEqual(_.sortBy(array), expected);
+        assert.strictEqual(func(expected, 3), 2);
+        assert.strictEqual(func(expected, symbol1), (isSortedIndex ? 3 : (Symbol ? 5 : 6)));
+        assert.strictEqual(func(expected, null), (isSortedIndex ? (Symbol ? 5 : 3) : 6));
+        assert.strictEqual(func(expected, undefined), isSortedIndex ? 6 : 7);
+        assert.strictEqual(func(expected, NaN), isSortedIndex ? 7 : 9);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('sortedIndexBy methods');
+
+  lodashStable.each(['sortedIndexBy', 'sortedLastIndexBy'], function(methodName) {
+    var func = _[methodName],
+        isSortedIndexBy = methodName == 'sortedIndexBy';
+
+    QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      func([30, 50], 40, function(assert) {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [40]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 30 }, { 'x': 50 }],
+          actual = func(objects, { 'x': 40 }, 'x');
+
+      assert.strictEqual(actual, 1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support arrays larger than `MAX_ARRAY_LENGTH / 2`', function(assert) {
+      assert.expect(12);
+
+      lodashStable.each([Math.ceil(MAX_ARRAY_LENGTH / 2), MAX_ARRAY_LENGTH], function(length) {
+        var array = [],
+            values = [MAX_ARRAY_LENGTH, NaN, undefined];
+
+        array.length = length;
+
+        lodashStable.each(values, function(value) {
+          var steps = 0;
+
+          var actual = func(array, value, function(value) {
+            steps++;
+            return value;
+          });
+
+          var expected = (isSortedIndexBy ? !lodashStable.isNaN(value) : lodashStable.isFinite(value))
+            ? 0
+            : Math.min(length, MAX_ARRAY_INDEX);
+
+          // Avoid false fails in older Firefox.
+          if (array.length == length) {
+            assert.ok(steps == 32 || steps == 33);
+            assert.strictEqual(actual, expected);
+          }
+          else {
+            skipAssert(assert, 2);
+          }
+        });
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('sortedIndexOf methods');
+
+  lodashStable.each(['sortedIndexOf', 'sortedLastIndexOf'], function(methodName) {
+    var func = _[methodName],
+        isSortedIndexOf = methodName == 'sortedIndexOf';
+
+    QUnit.test('`_.' + methodName + '` should perform a binary search', function(assert) {
+      assert.expect(1);
+
+      var sorted = [4, 4, 5, 5, 6, 6];
+      assert.deepEqual(func(sorted, 5), isSortedIndexOf ? 2 : 3);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.sortedUniq');
+
+  (function() {
+    QUnit.test('should return unique values of a sorted array', function(assert) {
+      assert.expect(3);
+
+      var expected = [1, 2, 3];
+
+      lodashStable.each([[1, 2, 3], [1, 1, 2, 2, 3], [1, 2, 3, 3, 3, 3, 3]], function(array) {
+        assert.deepEqual(_.sortedUniq(array), expected);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.split');
+
+  (function() {
+    QUnit.test('should split a string by `separator`', function(assert) {
+      assert.expect(3);
+
+      var string = 'abcde';
+      assert.deepEqual(_.split(string, 'c'), ['ab', 'de']);
+      assert.deepEqual(_.split(string, /[bd]/), ['a', 'c', 'e']);
+      assert.deepEqual(_.split(string, '', 2), ['a', 'b']);
+    });
+
+    QUnit.test('should return an array containing an empty string for empty values', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined, ''],
+          expected = lodashStable.map(values, lodashStable.constant(['']));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.split(value) : _.split();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var strings = ['abc', 'def', 'ghi'],
+          actual = lodashStable.map(strings, _.split);
+
+      assert.deepEqual(actual, [['abc'], ['def'], ['ghi']]);
+    });
+
+    QUnit.test('should allow mixed string and array prototype methods', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _('abc');
+        assert.strictEqual(wrapped.split('b').join(','), 'a,c');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.spread');
+
+  (function() {
+    function fn(a, b, c) {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should spread arguments to `func`', function(assert) {
+      assert.expect(1);
+
+      var spread = _.spread(fn);
+      assert.deepEqual(spread([4, 2]), [4, 2]);
+    });
+
+    QUnit.test('should accept a falsey `array` argument', function(assert) {
+      assert.expect(1);
+
+      var spread = _.spread(alwaysTrue),
+          expected = lodashStable.map(falsey, alwaysTrue);
+
+      var actual = lodashStable.map(falsey, function(array, index) {
+        try {
+          return index ? spread(array) : spread();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should provide the correct `func` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      var spread = _.spread(function() {
+        args = slice.call(arguments);
+      });
+
+      spread([4, 2], 'ignored');
+      assert.deepEqual(args, [4, 2]);
+    });
+
+    QUnit.test('should work with `start`', function(assert) {
+      assert.expect(1);
+
+      var spread = _.spread(fn, 1);
+      assert.deepEqual(spread(1, [2, 3, 4]), [1, 2, 3, 4]);
+    });
+
+    QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
+      assert.expect(1);
+
+      var values = [-1, NaN, 'a'],
+          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3, 4]));
+
+      var actual = lodashStable.map(values, function(value) {
+        var spread = _.spread(fn, value);
+        return spread([1, 2, 3, 4]);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should coerce `start` to an integer', function(assert) {
+      assert.expect(1);
+
+      var spread = _.spread(fn, 1.6);
+      assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.startCase');
+
+  (function() {
+    QUnit.test('should uppercase only the first character of each word', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.startCase('--foo-bar--'), 'Foo Bar');
+      assert.strictEqual(_.startCase('fooBar'), 'Foo Bar');
+      assert.strictEqual(_.startCase('__FOO_BAR__'), 'FOO BAR');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.startsWith');
+
+  (function() {
+    var string = 'abc';
+
+    QUnit.test('should return `true` if a string starts with `target`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.startsWith(string, 'a'), true);
+    });
+
+    QUnit.test('should return `false` if a string does not start with `target`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.startsWith(string, 'b'), false);
+    });
+
+    QUnit.test('should work with a `position` argument', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.startsWith(string, 'b', 1), true);
+    });
+
+    QUnit.test('should work with `position` >= `string.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
+        assert.strictEqual(_.startsWith(string, 'a', position), false);
+      });
+    });
+
+    QUnit.test('should treat falsey `position` values as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysTrue);
+
+      var actual = lodashStable.map(falsey, function(position) {
+        return _.startsWith(string, 'a', position);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should treat a negative `position` as `0`', function(assert) {
+      assert.expect(6);
+
+      lodashStable.each([-1, -3, -Infinity], function(position) {
+        assert.strictEqual(_.startsWith(string, 'a', position), true);
+        assert.strictEqual(_.startsWith(string, 'b', position), false);
+      });
+    });
+
+    QUnit.test('should coerce `position` to an integer', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.startsWith(string, 'bc', 1.2), true);
+    });
+
+    QUnit.test('should return `true` when `target` is an empty string regardless of `position`', function(assert) {
+      assert.expect(1);
+
+      assert.ok(lodashStable.every([-Infinity, NaN, -3, -1, 0, 1, 2, 3, 5, MAX_SAFE_INTEGER, Infinity], function(position) {
+        return _.startsWith(string, '', position, true);
+      }));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.startsWith and lodash.endsWith');
+
+  lodashStable.each(['startsWith', 'endsWith'], function(methodName) {
+    var func = _[methodName],
+        isStartsWith = methodName == 'startsWith';
+
+    var string = 'abc',
+        chr = isStartsWith ? 'a' : 'c';
+
+    QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(func(Object(string), chr), true);
+      assert.strictEqual(func({ 'toString': lodashStable.constant(string) }, chr), true);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `target` to a string', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(func(string, Object(chr)), true);
+      assert.strictEqual(func(string, { 'toString': lodashStable.constant(chr) }), true);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `position` to a number', function(assert) {
+      assert.expect(2);
+
+      var position = isStartsWith ? 1 : 2;
+      assert.strictEqual(func(string, 'b', Object(position)), true);
+      assert.strictEqual(func(string, 'b', { 'toString': lodashStable.constant(String(position)) }), true);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.subtract');
+
+  (function() {
+    QUnit.test('should subtract two numbers', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.subtract(6, 4), 2);
+      assert.strictEqual(_.subtract(-6, 4), -10);
+      assert.strictEqual(_.subtract(-6, -4), -2);
+    });
+
+    QUnit.test('should coerce arguments to numbers', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.subtract('6', '4'), 2);
+      assert.deepEqual(_.subtract('x', 'y'), NaN);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('math operator methods');
+
+  lodashStable.each(['add', 'divide', 'multiply', 'subtract'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return `0` when no arguments are given', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func(), 0);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with only one defined argument', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(func(6), 6);
+      assert.strictEqual(func(6, undefined), 6);
+      assert.strictEqual(func(undefined, 4), 4);
+    });
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(2);
+
+      var values = [0, '0', -0, '-0'],
+          expected = [[0, Infinity], ['0', Infinity], [-0, -Infinity], ['-0', -Infinity]];
+
+      lodashStable.times(2, function(index) {
+        var actual = lodashStable.map(values, function(value) {
+          var result = index ? func(undefined, value) : func(value);
+          return [result, 1 / result];
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert objects to `NaN`', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(func(0, {}), NaN);
+      assert.deepEqual(func({}, 0), NaN);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert symbols to `NaN`', function(assert) {
+      assert.expect(2);
+
+      if (Symbol) {
+        assert.deepEqual(func(0, symbol), NaN);
+        assert.deepEqual(func(symbol, 0), NaN);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = _(1)[methodName](2);
+        assert.notOk(actual instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var actual = _(1).chain()[methodName](2);
+        assert.ok(actual instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.sumBy');
+
+  (function() {
+    var array = [6, 4, 2],
+        objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
+
+    QUnit.test('should work with an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var actual = _.sumBy(objects, function(object) {
+        return object.a;
+      });
+
+      assert.deepEqual(actual, 6);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.sumBy(array, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [6]);
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var arrays = [[2], [3], [1]];
+      assert.strictEqual(_.sumBy(arrays, 0), 6);
+      assert.strictEqual(_.sumBy(objects, 'a'), 6);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('sum methods');
+
+  lodashStable.each(['sum', 'sumBy'], function(methodName) {
+    var array = [6, 4, 2],
+        func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return the sum of an array of numbers', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func(array), 12);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return `0` when passing empty `array` values', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(empties, alwaysZero);
+
+      var actual = lodashStable.map(empties, function(value) {
+        return func(value);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should skip `undefined` values', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func([1, undefined]), 1);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not skip `NaN` values', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func([1, NaN]), NaN);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not coerce values to numbers', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(func(['1', '2']), '12');
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.tail');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should accept a falsey `array` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyArray);
+
+      var actual = lodashStable.map(falsey, function(array, index) {
+        try {
+          return index ? _.tail(array) : _.tail();
+        } catch (e) {}
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should exclude the first element', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.tail(array), [2, 3]);
+    });
+
+    QUnit.test('should return an empty when querying empty arrays', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.tail([]), []);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.tail);
+
+      assert.deepEqual(actual, [[2, 3], [5, 6], [8, 9]]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            values = [];
+
+        var actual = _(array).tail().filter(function(value) {
+          values.push(value);
+          return false;
+        })
+        .value();
+
+        assert.deepEqual(actual, []);
+        assert.deepEqual(values, array.slice(1));
+
+        values = [];
+
+        actual = _(array).filter(function(value) {
+          values.push(value);
+          return isEven(value);
+        })
+        .tail()
+        .value();
+
+        assert.deepEqual(actual, _.tail(_.filter(array, isEven)));
+        assert.deepEqual(values, array);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should not execute subsequent iteratees on an empty array in a lazy sequence', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            iteratee = function() { pass = false; },
+            pass = true,
+            actual = _(array).slice(0, 1).tail().map(iteratee).value();
+
+        assert.ok(pass);
+        assert.deepEqual(actual, []);
+
+        pass = true;
+        actual = _(array).filter().slice(0, 1).tail().map(iteratee).value();
+
+        assert.ok(pass);
+        assert.deepEqual(actual, []);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.take');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should take the first two elements', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.take(array, 2), [1, 2]);
+    });
+
+    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? [1] : [];
+      });
+
+      var actual = lodashStable.map(falsey, function(n) {
+        return _.take(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an empty array when `n` < `1`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([0, -1, -Infinity], function(n) {
+        assert.deepEqual(_.take(array, n), []);
+      });
+    });
+
+    QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
+        assert.deepEqual(_.take(array, n), array);
+      });
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.take);
+
+      assert.deepEqual(actual, [[1], [4], [7]]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var array = lodashStable.range(1, LARGE_ARRAY_SIZE + 1),
+            predicate = function(value) { values.push(value); return isEven(value); },
+            values = [],
+            actual = _(array).take(2).take().value();
+
+        assert.deepEqual(actual, _.take(_.take(array, 2)));
+
+        actual = _(array).filter(predicate).take(2).take().value();
+        assert.deepEqual(values, [1, 2]);
+        assert.deepEqual(actual, _.take(_.take(_.filter(array, predicate), 2)));
+
+        actual = _(array).take(6).takeRight(4).take(2).takeRight().value();
+        assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(array, 6), 4), 2)));
+
+        values = [];
+
+        actual = _(array).take(array.length - 1).filter(predicate).take(6).takeRight(4).take(2).takeRight().value();
+        assert.deepEqual(values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+        assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2)));
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.takeRight');
+
+  (function() {
+    var array = [1, 2, 3];
+
+    QUnit.test('should take the last two elements', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeRight(array, 2), [2, 3]);
+    });
+
+    QUnit.test('should treat falsey `n` values, except `undefined`, as `0`', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, function(value) {
+        return value === undefined ? [3] : [];
+      });
+
+      var actual = lodashStable.map(falsey, function(n) {
+        return _.takeRight(array, n);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an empty array when `n` < `1`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([0, -1, -Infinity], function(n) {
+        assert.deepEqual(_.takeRight(array, n), []);
+      });
+    });
+
+    QUnit.test('should return all elements when `n` >= `array.length`', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each([3, 4, Math.pow(2, 32), Infinity], function(n) {
+        assert.deepEqual(_.takeRight(array, n), array);
+      });
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
+          actual = lodashStable.map(array, _.takeRight);
+
+      assert.deepEqual(actual, [[3], [6], [9]]);
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(6);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            predicate = function(value) { values.push(value); return isEven(value); },
+            values = [],
+            actual = _(array).takeRight(2).takeRight().value();
+
+        assert.deepEqual(actual, _.takeRight(_.takeRight(array)));
+
+        actual = _(array).filter(predicate).takeRight(2).takeRight().value();
+        assert.deepEqual(values, array);
+        assert.deepEqual(actual, _.takeRight(_.takeRight(_.filter(array, predicate), 2)));
+
+        actual = _(array).takeRight(6).take(4).takeRight(2).take().value();
+        assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(array, 6), 4), 2)));
+
+        values = [];
+
+        actual = _(array).filter(predicate).takeRight(6).take(4).takeRight(2).take().value();
+        assert.deepEqual(values, array);
+        assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2)));
+      }
+      else {
+        skipAssert(assert, 6);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.takeRightWhile');
+
+  (function() {
+    var array = [1, 2, 3, 4];
+
+    var objects = [
+      { 'a': 0, 'b': 0 },
+      { 'a': 1, 'b': 1 },
+      { 'a': 2, 'b': 2 }
+    ];
+
+    QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
+      assert.expect(1);
+
+      var actual = _.takeRightWhile(array, function(n) {
+        return n > 2;
+      });
+
+      assert.deepEqual(actual, [3, 4]);
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.takeRightWhile(array, function() {
+        args = slice.call(arguments);
+      });
+
+      assert.deepEqual(args, [4, 3, array]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeRightWhile(objects, { 'b': 2 }), objects.slice(2));
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeRightWhile(objects, ['b', 2]), objects.slice(2));
+    });
+
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeRightWhile(objects, 'b'), objects.slice(1));
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            predicate = function(n) { return n > 2; },
+            expected = _.takeRightWhile(array, predicate),
+            wrapped = _(array).takeRightWhile(predicate);
+
+        assert.deepEqual(wrapped.value(), expected);
+        assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
+        assert.strictEqual(wrapped.last(), _.last(expected));
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var args,
+            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            expected = [square(LARGE_ARRAY_SIZE), LARGE_ARRAY_SIZE - 1, lodashStable.map(array.slice(1), square)];
+
+        _(array).slice(1).takeRightWhile(function(value, index, array) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, [LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE - 1, array.slice(1)]);
+
+        _(array).slice(1).map(square).takeRightWhile(function(value, index, array) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        _(array).slice(1).map(square).takeRightWhile(function(value, index) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        _(array).slice(1).map(square).takeRightWhile(function(index) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, [square(LARGE_ARRAY_SIZE)]);
+
+        _(array).slice(1).map(square).takeRightWhile(function() {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, expected);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.takeWhile');
+
+  (function() {
+    var array = [1, 2, 3, 4];
+
+    var objects = [
+      { 'a': 2, 'b': 2 },
+      { 'a': 1, 'b': 1 },
+      { 'a': 0, 'b': 0 }
+    ];
+
+    QUnit.test('should take elements while `predicate` returns truthy', function(assert) {
+      assert.expect(1);
+
+      var actual = _.takeWhile(array, function(n) {
+        return n < 3;
+      });
+
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.takeWhile(array, function() {
+        args = slice.call(arguments);
+      });
+
+      assert.deepEqual(args, [1, 0, array]);
+    });
+
+    QUnit.test('should work with `_.matches` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeWhile(objects, { 'b': 2 }), objects.slice(0, 1));
+    });
+
+    QUnit.test('should work with `_.matchesProperty` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeWhile(objects, ['b', 2]), objects.slice(0, 1));
+    });
+    QUnit.test('should work with `_.property` shorthands', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.takeWhile(objects, 'b'), objects.slice(0, 2));
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            predicate = function(n) { return n < 3; },
+            expected = _.takeWhile(array, predicate),
+            wrapped = _(array).takeWhile(predicate);
+
+        assert.deepEqual(wrapped.value(), expected);
+        assert.deepEqual(wrapped.reverse().value(), expected.slice().reverse());
+        assert.strictEqual(wrapped.last(), _.last(expected));
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence with `take`', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE);
+
+        var actual = _(array)
+          .takeWhile(function(n) { return n < 4; })
+          .take(2)
+          .takeWhile(function(n) { return n == 0; })
+          .value();
+
+        assert.deepEqual(actual, [0]);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should provide the correct `predicate` arguments in a lazy sequence', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var args,
+            array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            expected = [1, 0, lodashStable.map(array.slice(1), square)];
+
+        _(array).slice(1).takeWhile(function(value, index, array) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, [1, 0, array.slice(1)]);
+
+        _(array).slice(1).map(square).takeWhile(function(value, index, array) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        _(array).slice(1).map(square).takeWhile(function(value, index) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, expected);
+
+        _(array).slice(1).map(square).takeWhile(function(value) {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, [1]);
+
+        _(array).slice(1).map(square).takeWhile(function() {
+          args = slice.call(arguments);
+        }).value();
+
+        assert.deepEqual(args, expected);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.tap');
+
+  (function() {
+    QUnit.test('should intercept and return the given value', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var intercepted,
+            array = [1, 2, 3];
+
+        var actual = _.tap(array, function(value) {
+          intercepted = value;
+        });
+
+        assert.strictEqual(actual, array);
+        assert.strictEqual(intercepted, array);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should intercept unwrapped values and return wrapped values when chaining', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var intercepted,
+            array = [1, 2, 3];
+
+        var wrapped = _(array).tap(function(value) {
+          intercepted = value;
+          value.pop();
+        });
+
+        assert.ok(wrapped instanceof _);
+
+        wrapped.value();
+        assert.strictEqual(intercepted, array);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.template');
+
+  (function() {
+    QUnit.test('should escape values in "escape" delimiters', function(assert) {
+      assert.expect(1);
+
+      var strings = ['<p><%- value %></p>', '<p><%-value%></p>', '<p><%-\nvalue\n%></p>'],
+          expected = lodashStable.map(strings, lodashStable.constant('<p>&amp;&lt;&gt;&quot;&#39;&#96;\/</p>')),
+          data = { 'value': '&<>"\'`\/' };
+
+      var actual = lodashStable.map(strings, function(string) {
+        return _.template(string)(data);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not reference `_.escape` when "escape" delimiters are not used', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= typeof __e %>');
+      assert.strictEqual(compiled({}), 'undefined');
+    });
+
+    QUnit.test('should evaluate JavaScript in "evaluate" delimiters', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template(
+        '<ul><%\
+        for (var key in collection) {\
+          %><li><%= collection[key] %></li><%\
+        } %></ul>'
+      );
+
+      var data = { 'collection': { 'a': 'A', 'b': 'B' } },
+          actual = compiled(data);
+
+      assert.strictEqual(actual, '<ul><li>A</li><li>B</li></ul>');
+    });
+
+    QUnit.test('should support "evaluate" delimiters with single line comments (test production builds)', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<% // A code comment. %><% if (value) { %>yap<% } else { %>nope<% } %>'),
+          data = { 'value': true };
+
+      assert.strictEqual(compiled(data), 'yap');
+    });
+
+    QUnit.test('should support referencing variables declared in "evaluate" delimiters from other delimiters', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<% var b = a; %><%= b.value %>'),
+          data = { 'a': { 'value': 1 } };
+
+      assert.strictEqual(compiled(data), '1');
+    });
+
+    QUnit.test('should interpolate data properties in "interpolate" delimiters', function(assert) {
+      assert.expect(1);
+
+      var strings = ['<%= a %>BC', '<%=a%>BC', '<%=\na\n%>BC'],
+          expected = lodashStable.map(strings, lodashStable.constant('ABC')),
+          data = { 'a': 'A' };
+
+      var actual = lodashStable.map(strings, function(string) {
+        return _.template(string)(data);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should support "interpolate" delimiters with escaped values', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= a ? "a=\\"A\\"" : "" %>'),
+          data = { 'a': true };
+
+      assert.strictEqual(compiled(data), 'a="A"');
+    });
+
+    QUnit.test('should support "interpolate" delimiters containing ternary operators', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= value ? value : "b" %>'),
+          data = { 'value': 'a' };
+
+      assert.strictEqual(compiled(data), 'a');
+    });
+
+    QUnit.test('should support "interpolate" delimiters containing global values', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= typeof Math.abs %>');
+
+      try {
+        var actual = compiled();
+      } catch (e) {}
+
+      assert.strictEqual(actual, 'function');
+    });
+
+    QUnit.test('should support complex "interpolate" delimiters', function(assert) {
+      assert.expect(22);
+
+      lodashStable.forOwn({
+        '<%= a + b %>': '3',
+        '<%= b - a %>': '1',
+        '<%= a = b %>': '2',
+        '<%= !a %>': 'false',
+        '<%= ~a %>': '-2',
+        '<%= a * b %>': '2',
+        '<%= a / b %>': '0.5',
+        '<%= a % b %>': '1',
+        '<%= a >> b %>': '0',
+        '<%= a << b %>': '4',
+        '<%= a & b %>': '0',
+        '<%= a ^ b %>': '3',
+        '<%= a | b %>': '3',
+        '<%= {}.toString.call(0) %>': numberTag,
+        '<%= a.toFixed(2) %>': '1.00',
+        '<%= obj["a"] %>': '1',
+        '<%= delete a %>': 'true',
+        '<%= "a" in obj %>': 'true',
+        '<%= obj instanceof Object %>': 'true',
+        '<%= new Boolean %>': 'false',
+        '<%= typeof a %>': 'number',
+        '<%= void a %>': ''
+      },
+      function(value, key) {
+        var compiled = _.template(key),
+            data = { 'a': 1, 'b': 2 };
+
+        assert.strictEqual(compiled(data), value, key);
+      });
+    });
+
+    QUnit.test('should support ES6 template delimiters', function(assert) {
+      assert.expect(2);
+
+      var data = { 'value': 2 };
+      assert.strictEqual(_.template('1${value}3')(data), '123');
+      assert.strictEqual(_.template('${"{" + value + "\\}"}')(data), '{2}');
+    });
+
+    QUnit.test('should support the "imports" option', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= a %>', { 'imports': { 'a': 1 } });
+      assert.strictEqual(compiled({}), '1');
+    });
+
+    QUnit.test('should support the "variable" options', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template(
+        '<% _.each( data.a, function( value ) { %>' +
+            '<%= value.valueOf() %>' +
+        '<% }) %>', { 'variable': 'data' }
+      );
+
+      var data = { 'a': [1, 2, 3] };
+
+      try {
+        assert.strictEqual(compiled(data), '123');
+      } catch (e) {
+        assert.ok(false, e.message);
+      }
+    });
+
+    QUnit.test('should support custom delimiters', function(assert) {
+      assert.expect(2);
+
+      lodashStable.times(2, function(index) {
+        var settingsClone = lodashStable.clone(_.templateSettings);
+
+        var settings = lodashStable.assign(index ? _.templateSettings : {}, {
+          'escape': /\{\{-([\s\S]+?)\}\}/g,
+          'evaluate': /\{\{([\s\S]+?)\}\}/g,
+          'interpolate': /\{\{=([\s\S]+?)\}\}/g
+        });
+
+        var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
+            compiled = _.template('<ul>{{ _.each(collection, function(value, index) {}}<li>{{= index }}: {{- value }}</li>{{}); }}</ul>', index ? null : settings),
+            data = { 'collection': ['a & A', 'b & B'] };
+
+        assert.strictEqual(compiled(data), expected);
+        lodashStable.assign(_.templateSettings, settingsClone);
+      });
+    });
+
+    QUnit.test('should support custom delimiters containing special characters', function(assert) {
+      assert.expect(2);
+
+      lodashStable.times(2, function(index) {
+        var settingsClone = lodashStable.clone(_.templateSettings);
+
+        var settings = lodashStable.assign(index ? _.templateSettings : {}, {
+          'escape': /<\?-([\s\S]+?)\?>/g,
+          'evaluate': /<\?([\s\S]+?)\?>/g,
+          'interpolate': /<\?=([\s\S]+?)\?>/g
+        });
+
+        var expected = '<ul><li>0: a &amp; A</li><li>1: b &amp; B</li></ul>',
+            compiled = _.template('<ul><? _.each(collection, function(value, index) { ?><li><?= index ?>: <?- value ?></li><? }); ?></ul>', index ? null : settings),
+            data = { 'collection': ['a & A', 'b & B'] };
+
+        assert.strictEqual(compiled(data), expected);
+        lodashStable.assign(_.templateSettings, settingsClone);
+      });
+    });
+
+    QUnit.test('should use a `with` statement by default', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= index %><%= collection[index] %><% _.each(collection, function(value, index) { %><%= index %><% }); %>'),
+          actual = compiled({ 'index': 1, 'collection': ['a', 'b', 'c'] });
+
+      assert.strictEqual(actual, '1b012');
+    });
+
+    QUnit.test('should use `_.templateSettings.imports._.templateSettings`', function(assert) {
+      assert.expect(1);
+
+      var lodash = _.templateSettings.imports._,
+          settingsClone = lodashStable.clone(lodash.templateSettings);
+
+      lodash.templateSettings = lodashStable.assign(lodash.templateSettings, {
+        'interpolate': /\{\{=([\s\S]+?)\}\}/g
+      });
+
+      var compiled = _.template('{{= a }}');
+      assert.strictEqual(compiled({ 'a': 1 }), '1');
+
+      if (settingsClone) {
+        lodashStable.assign(lodash.templateSettings, settingsClone);
+      } else {
+        delete lodash.templateSettings;
+      }
+    });
+
+    QUnit.test('should fallback to `_.templateSettings`', function(assert) {
+      assert.expect(1);
+
+      var lodash = _.templateSettings.imports._,
+          delimiter = _.templateSettings.interpolate;
+
+      _.templateSettings.imports._ = { 'escape': lodashStable.escape };
+      _.templateSettings.interpolate = /\{\{=([\s\S]+?)\}\}/g;
+
+      var compiled = _.template('{{= a }}');
+      assert.strictEqual(compiled({ 'a': 1 }), '1');
+
+      _.templateSettings.imports._ = lodash;
+      _.templateSettings.interpolate = delimiter;
+    });
+
+    QUnit.test('should ignore `null` delimiters', function(assert) {
+      assert.expect(3);
+
+      var delimiter = {
+        'escape': /\{\{-([\s\S]+?)\}\}/g,
+        'evaluate': /\{\{([\s\S]+?)\}\}/g,
+        'interpolate': /\{\{=([\s\S]+?)\}\}/g
+      };
+
+      lodashStable.forOwn({
+        'escape': '{{- a }}',
+        'evaluate': '{{ print(a) }}',
+        'interpolate': '{{= a }}'
+      },
+      function(value, key) {
+        var settings = { 'escape': null, 'evaluate': null, 'interpolate': null };
+        settings[key] = delimiter[key];
+
+        var expected = '1 <%- a %> <% print(a) %> <%= a %>',
+            compiled = _.template(value + ' <%- a %> <% print(a) %> <%= a %>', settings),
+            data = { 'a': 1 };
+
+        assert.strictEqual(compiled(data), expected);
+      });
+    });
+
+    QUnit.test('should work without delimiters', function(assert) {
+      assert.expect(1);
+
+      var expected = 'abc';
+      assert.strictEqual(_.template(expected)({}), expected);
+    });
+
+    QUnit.test('should work with `this` references', function(assert) {
+      assert.expect(2);
+
+      var compiled = _.template('a<%= this.String("b") %>c');
+      assert.strictEqual(compiled(), 'abc');
+
+      var object = { 'b': 'B' };
+      object.compiled = _.template('A<%= this.b %>C', { 'variable': 'obj' });
+      assert.strictEqual(object.compiled(), 'ABC');
+    });
+
+    QUnit.test('should work with backslashes', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= a %> \\b'),
+          data = { 'a': 'A' };
+
+      assert.strictEqual(compiled(data), 'A \\b');
+    });
+
+    QUnit.test('should work with escaped characters in string literals', function(assert) {
+      assert.expect(2);
+
+      var compiled = _.template('<% print("\'\\n\\r\\t\\u2028\\u2029\\\\") %>');
+      assert.strictEqual(compiled(), "'\n\r\t\u2028\u2029\\");
+
+      var data = { 'a': 'A' };
+      compiled = _.template('\'\n\r\t<%= a %>\u2028\u2029\\"');
+      assert.strictEqual(compiled(data), '\'\n\r\tA\u2028\u2029\\"');
+    });
+
+    QUnit.test('should handle \\u2028 & \\u2029 characters', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('\u2028<%= "\\u2028\\u2029" %>\u2029');
+      assert.strictEqual(compiled(), '\u2028\u2028\u2029\u2029');
+    });
+
+    QUnit.test('should work with statements containing quotes', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template("<%\
+        if (a == 'A' || a == \"a\") {\
+          %>'a',\"A\"<%\
+        } %>"
+      );
+
+      var data = { 'a': 'A' };
+      assert.strictEqual(compiled(data), "'a',\"A\"");
+    });
+
+    QUnit.test('should work with templates containing newlines and comments', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%\n\
+        // A code comment.\n\
+        if (value) { value += 3; }\n\
+        %><p><%= value %></p>'
+      );
+
+      assert.strictEqual(compiled({ 'value': 3 }), '<p>6</p>');
+    });
+
+    QUnit.test('should not error with IE conditional comments enabled (test with development build)', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template(''),
+          pass = true;
+
+      /*@cc_on @*/
+      try {
+        compiled();
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass);
+    });
+
+    QUnit.test('should tokenize delimiters', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<span class="icon-<%= type %>2"></span>'),
+          data = { 'type': 1 };
+
+      assert.strictEqual(compiled(data), '<span class="icon-12"></span>');
+    });
+
+    QUnit.test('should evaluate delimiters once', function(assert) {
+      assert.expect(1);
+
+      var actual = [],
+          compiled = _.template('<%= func("a") %><%- func("b") %><% func("c") %>'),
+          data = { 'func': function(value) { actual.push(value); } };
+
+      compiled(data);
+      assert.deepEqual(actual, ['a', 'b', 'c']);
+    });
+
+    QUnit.test('should match delimiters before escaping text', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<<\n a \n>>', { 'evaluate': /<<(.*?)>>/g });
+      assert.strictEqual(compiled(), '<<\n a \n>>');
+    });
+
+    QUnit.test('should resolve nullish values to an empty string', function(assert) {
+      assert.expect(3);
+
+      var compiled = _.template('<%= a %><%- a %>'),
+          data = { 'a': null };
+
+      assert.strictEqual(compiled(data), '');
+
+      data = { 'a': undefined };
+      assert.strictEqual(compiled(data), '');
+
+      data = { 'a': {} };
+      compiled = _.template('<%= a.b %><%- a.b %>');
+      assert.strictEqual(compiled(data), '');
+    });
+
+    QUnit.test('should return an empty string for empty values', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined, ''],
+          expected = lodashStable.map(values, alwaysEmptyString),
+          data = { 'a': 1 };
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var compiled = index ? _.template(value) : _.template();
+        return compiled(data);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should parse delimiters without newlines', function(assert) {
+      assert.expect(1);
+
+      var expected = '<<\nprint("<p>" + (value ? "yes" : "no") + "</p>")\n>>',
+          compiled = _.template(expected, { 'evaluate': /<<(.+?)>>/g }),
+          data = { 'value': true };
+
+      assert.strictEqual(compiled(data), expected);
+    });
+
+    QUnit.test('should support recursive calls', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('<%= a %><% a = _.template(c)(obj) %><%= a %>'),
+          data = { 'a': 'A', 'b': 'B', 'c': '<%= b %>' };
+
+      assert.strictEqual(compiled(data), 'AB');
+    });
+
+    QUnit.test('should coerce `text` argument to a string', function(assert) {
+      assert.expect(1);
+
+      var object = { 'toString': lodashStable.constant('<%= a %>') },
+          data = { 'a': 1 };
+
+      assert.strictEqual(_.template(object)(data), '1');
+    });
+
+    QUnit.test('should not modify the `options` object', function(assert) {
+      assert.expect(1);
+
+      var options = {};
+      _.template('', options);
+      assert.deepEqual(options, {});
+    });
+
+    QUnit.test('should not modify `_.templateSettings` when `options` are given', function(assert) {
+      assert.expect(2);
+
+      var data = { 'a': 1 };
+
+      assert.notOk('a' in _.templateSettings);
+      _.template('', {}, data);
+      assert.notOk('a' in _.templateSettings);
+
+      delete _.templateSettings.a;
+    });
+
+    QUnit.test('should not error for non-object `data` and `options` values', function(assert) {
+      assert.expect(2);
+
+      var pass = true;
+
+      try {
+        _.template('')(1);
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass, '`data` value');
+
+      pass = true;
+
+      try {
+        _.template('', 1)(1);
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass, '`options` value');
+    });
+
+    QUnit.test('should expose the source on compiled templates', function(assert) {
+      assert.expect(1);
+
+      var compiled = _.template('x'),
+          values = [String(compiled), compiled.source],
+          expected = lodashStable.map(values, alwaysTrue);
+
+      var actual = lodashStable.map(values, function(value) {
+        return lodashStable.includes(value, '__p');
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should expose the source on SyntaxErrors', function(assert) {
+      assert.expect(1);
+
+      try {
+        _.template('<% if x %>');
+      } catch (e) {
+        var source = e.source;
+      }
+      assert.ok(lodashStable.includes(source, '__p'));
+    });
+
+    QUnit.test('should not include sourceURLs in the source', function(assert) {
+      assert.expect(1);
+
+      var options = { 'sourceURL': '/a/b/c' },
+          compiled = _.template('x', options),
+          values = [compiled.source, undefined];
+
+      try {
+        _.template('<% if x %>', options);
+      } catch (e) {
+        values[1] = e.source;
+      }
+      var expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(values, function(value) {
+        return lodashStable.includes(value, 'sourceURL');
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = ['<%= a %>', '<%- b %>', '<% print(c) %>'],
+          compiles = lodashStable.map(array, _.template),
+          data = { 'a': 'one', 'b': '`two`', 'c': 'three' };
+
+      var actual = lodashStable.map(compiles, function(compiled) {
+        return compiled(data);
+      });
+
+      assert.deepEqual(actual, ['one', '&#96;two&#96;', 'three']);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.truncate');
+
+  (function() {
+    var string = 'hi-diddly-ho there, neighborino';
+
+    QUnit.test('should use a default `length` of `30`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.truncate(string), 'hi-diddly-ho there, neighbo...');
+    });
+
+    QUnit.test('should not truncate if `string` is <= `length`', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.truncate(string, { 'length': string.length }), string);
+      assert.strictEqual(_.truncate(string, { 'length': string.length + 2 }), string);
+    });
+
+    QUnit.test('should truncate string the given length', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.truncate(string, { 'length': 24 }), 'hi-diddly-ho there, n...');
+    });
+
+    QUnit.test('should support a `omission` option', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.truncate(string, { 'omission': ' [...]' }), 'hi-diddly-ho there, neig [...]');
+    });
+
+    QUnit.test('should coerce nullish `omission` values to strings', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.truncate(string, { 'omission': null }), 'hi-diddly-ho there, neighbnull');
+      assert.strictEqual(_.truncate(string, { 'omission': undefined }), 'hi-diddly-ho there, nundefined');
+    });
+
+    QUnit.test('should support a `length` option', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.truncate(string, { 'length': 4 }), 'h...');
+    });
+
+    QUnit.test('should support a `separator` option', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': ' ' }), 'hi-diddly-ho there,...');
+      assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/ }), 'hi-diddly-ho there...');
+      assert.strictEqual(_.truncate(string, { 'length': 24, 'separator': /,? +/g }), 'hi-diddly-ho there...');
+    });
+
+    QUnit.test('should treat negative `length` as `0`', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each([0, -2], function(length) {
+        assert.strictEqual(_.truncate(string, { 'length': length }), '...');
+      });
+    });
+
+    QUnit.test('should coerce `length` to an integer', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['', NaN, 4.6, '4'], function(length, index) {
+        var actual = index > 1 ? 'h...' : '...';
+        assert.strictEqual(_.truncate(string, { 'length': { 'valueOf': lodashStable.constant(length) } }), actual);
+      });
+    });
+
+    QUnit.test('should coerce `string` to a string', function(assert) {
+      assert.expect(2);
+
+      assert.strictEqual(_.truncate(Object(string), { 'length': 4 }), 'h...');
+      assert.strictEqual(_.truncate({ 'toString': lodashStable.constant(string) }, { 'length': 5 }), 'hi...');
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map([string, string, string], _.truncate),
+          truncated = 'hi-diddly-ho there, neighbo...';
+
+      assert.deepEqual(actual, [truncated, truncated, truncated]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.throttle');
+
+  (function() {
+    QUnit.test('should throttle a function', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          throttled = _.throttle(function() { callCount++; }, 32);
+
+      throttled();
+      throttled();
+      throttled();
+
+      var lastCount = callCount;
+      assert.ok(callCount > 0);
+
+      setTimeout(function() {
+        assert.ok(callCount > lastCount);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('subsequent calls should return the result of the first call', function(assert) {
+      assert.expect(5);
+
+      var done = assert.async();
+
+      var throttled = _.throttle(identity, 32),
+          result = [throttled('a'), throttled('b')];
+
+      assert.deepEqual(result, ['a', 'a']);
+
+      setTimeout(function() {
+        var result = [throttled('x'), throttled('y')];
+        assert.notEqual(result[0], 'a');
+        assert.notStrictEqual(result[0], undefined);
+
+        assert.notEqual(result[1], 'y');
+        assert.notStrictEqual(result[1], undefined);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('should clear timeout when `func` is called', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      if (!isModularize) {
+        var callCount = 0,
+            dateCount = 0;
+
+        var getTime = function() {
+          return ++dateCount == 5
+            ? Infinity
+            : +new Date;
+        };
+
+        var lodash = _.runInContext(lodashStable.assign({}, root, {
+          'Date': lodashStable.assign(function() {
+            return { 'getTime': getTime };
+          }, {
+            'now': Date.now
+          })
+        }));
+
+        var throttled = lodash.throttle(function() { callCount++; }, 32);
+
+        throttled();
+        throttled();
+
+        setTimeout(function() {
+          assert.strictEqual(callCount, 2);
+          done();
+        }, 64);
+      }
+      else {
+        skipAssert(assert);
+        done();
+      }
+    });
+
+    QUnit.test('should not trigger a trailing call when invoked once', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          throttled = _.throttle(function() { callCount++; }, 32);
+
+      throttled();
+      assert.strictEqual(callCount, 1);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+        done();
+      }, 64);
+    });
+
+    lodashStable.times(2, function(index) {
+      QUnit.test('should trigger a call when invoked repeatedly' + (index ? ' and `leading` is `false`' : ''), function(assert) {
+        assert.expect(1);
+
+        var done = assert.async();
+
+        var callCount = 0,
+            limit = (argv || isPhantom) ? 1000 : 320,
+            options = index ? { 'leading': false } : {},
+            throttled = _.throttle(function() { callCount++; }, 32, options);
+
+        var start = +new Date;
+        while ((new Date - start) < limit) {
+          throttled();
+        }
+        var actual = callCount > 1;
+        setTimeout(function() {
+          assert.ok(actual);
+          done();
+        }, 1);
+      });
+    });
+
+    QUnit.test('should trigger a second throttled call as soon as possible', function(assert) {
+      assert.expect(3);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var throttled = _.throttle(function() {
+        callCount++;
+      }, 128, { 'leading': false });
+
+      throttled();
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+        throttled();
+      }, 192);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+      }, 254);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        done();
+      }, 384);
+    });
+
+    QUnit.test('should apply default options', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          throttled = _.throttle(function() { callCount++; }, 32, {});
+
+      throttled();
+      throttled();
+      assert.strictEqual(callCount, 1);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 2);
+        done();
+      }, 128);
+    });
+
+    QUnit.test('should support a `leading` option', function(assert) {
+      assert.expect(2);
+
+      var withLeading = _.throttle(identity, 32, { 'leading': true });
+      assert.strictEqual(withLeading('a'), 'a');
+
+      var withoutLeading = _.throttle(identity, 32, { 'leading': false });
+      assert.strictEqual(withoutLeading('a'), undefined);
+    });
+
+    QUnit.test('should support a `trailing` option', function(assert) {
+      assert.expect(6);
+
+      var done = assert.async();
+
+      var withCount = 0,
+          withoutCount = 0;
+
+      var withTrailing = _.throttle(function(value) {
+        withCount++;
+        return value;
+      }, 64, { 'trailing': true });
+
+      var withoutTrailing = _.throttle(function(value) {
+        withoutCount++;
+        return value;
+      }, 64, { 'trailing': false });
+
+      assert.strictEqual(withTrailing('a'), 'a');
+      assert.strictEqual(withTrailing('b'), 'a');
+
+      assert.strictEqual(withoutTrailing('a'), 'a');
+      assert.strictEqual(withoutTrailing('b'), 'a');
+
+      setTimeout(function() {
+        assert.strictEqual(withCount, 2);
+        assert.strictEqual(withoutCount, 1);
+        done();
+      }, 256);
+    });
+
+    QUnit.test('should not update `lastCalled`, at the end of the timeout, when `trailing` is `false`', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var throttled = _.throttle(function() {
+        callCount++;
+      }, 64, { 'trailing': false });
+
+      throttled();
+      throttled();
+
+      setTimeout(function() {
+        throttled();
+        throttled();
+      }, 96);
+
+      setTimeout(function() {
+        assert.ok(callCount > 1);
+        done();
+      }, 192);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.debounce and lodash.throttle');
+
+  lodashStable.each(['debounce', 'throttle'], function(methodName) {
+    var func = _[methodName],
+        isDebounce = methodName == 'debounce';
+
+    QUnit.test('`_.' + methodName + '` should not error for non-object `options` values', function(assert) {
+      assert.expect(1);
+
+      var pass = true;
+
+      try {
+        func(noop, 32, 1);
+      } catch (e) {
+        pass = false;
+      }
+      assert.ok(pass);
+    });
+
+    QUnit.test('`_.' + methodName + '` should use a default `wait` of `0`', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          funced = func(function() { callCount++; });
+
+      funced();
+
+      setTimeout(function() {
+        funced();
+        assert.strictEqual(callCount, isDebounce ? 1 : 2);
+        done();
+      }, 32);
+    });
+
+    QUnit.test('`_.' + methodName + '` should invoke `func` with the correct `this` binding', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var actual = [],
+          object = { 'funced': func(function() { actual.push(this); }, 32) },
+          expected = lodashStable.times(isDebounce ? 1 : 2, lodashStable.constant(object));
+
+      object.funced();
+      if (!isDebounce) {
+        object.funced();
+      }
+      setTimeout(function() {
+        assert.deepEqual(actual, expected);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('`_.' + methodName + '` supports recursive calls', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var actual = [],
+          args = lodashStable.map(['a', 'b', 'c'], function(chr) { return [{}, chr]; }),
+          expected = args.slice(),
+          queue = args.slice();
+
+      var funced = func(function() {
+        var current = [this];
+        push.apply(current, arguments);
+        actual.push(current);
+
+        var next = queue.shift();
+        if (next) {
+          funced.call(next[0], next[1]);
+        }
+      }, 32);
+
+      var next = queue.shift();
+      funced.call(next[0], next[1]);
+      assert.deepEqual(actual, expected.slice(0, isDebounce ? 0 : 1));
+
+      setTimeout(function() {
+        assert.deepEqual(actual, expected.slice(0, actual.length));
+        done();
+      }, 256);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work if the system time is set backwards', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      if (!isModularize) {
+        var callCount = 0,
+            dateCount = 0;
+
+        var getTime = function() {
+          return ++dateCount === 4
+            ? +new Date(2012, 3, 23, 23, 27, 18)
+            : +new Date;
+        };
+
+        var lodash = _.runInContext(lodashStable.assign({}, root, {
+          'Date': lodashStable.assign(function() {
+            return { 'getTime': getTime, 'valueOf': getTime };
+          }, {
+            'now': Date.now
+          })
+        }));
+
+        var funced = lodash[methodName](function() {
+          callCount++;
+        }, 32);
+
+        funced();
+
+        setTimeout(function() {
+          funced();
+          assert.strictEqual(callCount, isDebounce ? 1 : 2);
+          done();
+        }, 64);
+      }
+      else {
+        skipAssert(assert);
+        done();
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should support cancelling delayed calls', function(assert) {
+      assert.expect(1);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var funced = func(function() {
+        callCount++;
+      }, 32, { 'leading': false });
+
+      funced();
+      funced.cancel();
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 0);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('`_.' + methodName + '` should reset `lastCalled` after cancelling', function(assert) {
+      assert.expect(3);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var funced = func(function() {
+        return ++callCount;
+      }, 32, { 'leading': true });
+
+      assert.strictEqual(funced(), 1);
+      funced.cancel();
+
+      assert.strictEqual(funced(), 2);
+      funced();
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 3);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support flushing delayed calls', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0;
+
+      var funced = func(function() {
+        return ++callCount;
+      }, 32, { 'leading': false });
+
+      funced();
+      assert.strictEqual(funced.flush(), 1);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 1);
+        done();
+      }, 64);
+    });
+
+    QUnit.test('`_.' + methodName + '` should noop `cancel` and `flush` when nothing is queued', function(assert) {
+      assert.expect(2);
+
+      var done = assert.async();
+
+      var callCount = 0,
+          funced = func(function() { callCount++; }, 32);
+
+      funced.cancel();
+      assert.strictEqual(funced.flush(), undefined);
+
+      setTimeout(function() {
+        assert.strictEqual(callCount, 0);
+        done();
+      }, 64);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.times');
+
+  (function() {
+    QUnit.test('should coerce non-finite `n` values to `0`', function(assert) {
+      assert.expect(3);
+
+      lodashStable.each([-Infinity, NaN, Infinity], function(n) {
+        assert.deepEqual(_.times(n), []);
+      });
+    });
+
+    QUnit.test('should coerce `n` to an integer', function(assert) {
+      assert.expect(1);
+
+      var actual = _.times(2.6, _.indentify);
+      assert.deepEqual(actual, [0, 1]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.times(1, function(assert) {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [0]);
+    });
+
+    QUnit.test('should use `_.identity` when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant([0, 1, 2]));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.times(3, value) : _.times(3);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an array of the results of each `iteratee` execution', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.times(3, doubled), [0, 2, 4]);
+    });
+
+    QUnit.test('should return an empty array for falsey and negative `n` arguments', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat(-1, -Infinity),
+          expected = lodashStable.map(values, alwaysEmptyArray);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.times(value) : _.times();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.deepEqual(_(3).times(), [0, 1, 2]);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        assert.ok(_(3).chain().times() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toArray');
+
+  (function() {
+    QUnit.test('should convert objects to arrays', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(_.toArray({ 'a': 1, 'b': 2 }), [1, 2]);
+    });
+
+    QUnit.test('should convert strings to arrays', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(_.toArray(''), []);
+      assert.deepEqual(_.toArray('ab'), ['a', 'b']);
+      assert.deepEqual(_.toArray(Object('ab')), ['a', 'b']);
+    });
+
+    QUnit.test('should convert iterables to arrays', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm && Symbol && Symbol.iterator) {
+        var object = { '0': 'a', 'length': 1 };
+        object[Symbol.iterator] = arrayProto[Symbol.iterator];
+
+        assert.deepEqual(_.toArray(object), ['a']);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            actual = _(array).slice(1).map(String).toArray().value();
+
+        assert.deepEqual(actual, lodashStable.map(array.slice(1), String));
+
+        var object = lodashStable.zipObject(lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
+          return ['key' + index, index];
+        }));
+
+        actual = _(object).toArray().slice(1).map(String).value();
+        assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String));
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toLower');
+
+  (function() {
+    QUnit.test('should convert whole string to lower case', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(_.toLower('--Foo-Bar--'), '--foo-bar--');
+      assert.deepEqual(_.toLower('fooBar'), 'foobar');
+      assert.deepEqual(_.toLower('__FOO_BAR__'), '__foo_bar__');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toUpper');
+
+  (function() {
+    QUnit.test('should convert whole string to upper case', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(_.toUpper('--Foo-Bar'), '--FOO-BAR');
+      assert.deepEqual(_.toUpper('fooBar'), 'FOOBAR');
+      assert.deepEqual(_.toUpper('__FOO_BAR__'), '__FOO_BAR__');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.slice and lodash.toArray');
+
+  lodashStable.each(['slice', 'toArray'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        array = [1, 2, 3],
+        func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return a dense array', function(assert) {
+      assert.expect(3);
+
+      var sparse = Array(3);
+      sparse[1] = 2;
+
+      var actual = func(sparse);
+
+      assert.ok('0' in actual);
+      assert.ok('2' in actual);
+      assert.deepEqual(actual, sparse);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat array-like objects like arrays', function(assert) {
+      assert.expect(2);
+
+      var object = { '0': 'a', '1': 'b', '2': 'c', 'length': 3 };
+      assert.deepEqual(func(object), ['a', 'b', 'c']);
+      assert.deepEqual(func(args), array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a shallow clone of arrays', function(assert) {
+      assert.expect(2);
+
+      var actual = func(array);
+      assert.deepEqual(actual, array);
+      assert.notStrictEqual(actual, array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with a node list for `collection`', function(assert) {
+      assert.expect(1);
+
+      if (document) {
+        try {
+          var actual = func(document.getElementsByTagName('body'));
+        } catch (e) {}
+
+        assert.deepEqual(actual, [body]);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('toInteger methods');
+
+  lodashStable.each(['toInteger', 'toSafeInteger'], function(methodName) {
+    var func = _[methodName],
+        isSafe = methodName == 'toSafeInteger';
+
+    QUnit.test('`_.' + methodName + '` should convert values to integers', function(assert) {
+      assert.expect(6);
+
+      assert.strictEqual(func(-5.6), -5);
+      assert.strictEqual(func('5.6'), 5);
+      assert.strictEqual(func(), 0);
+      assert.strictEqual(func(NaN), 0);
+
+      var expected = isSafe ? MAX_SAFE_INTEGER : MAX_INTEGER;
+      assert.strictEqual(func(Infinity), expected);
+      assert.strictEqual(func(-Infinity), -expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support `value` of `-0`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(1 / func(-0), -Infinity);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toLength');
+
+  (function() {
+    QUnit.test('should return a valid length', function(assert) {
+      assert.expect(4);
+
+      assert.strictEqual(_.toLength(-1), 0);
+      assert.strictEqual(_.toLength('1'), 1);
+      assert.strictEqual(_.toLength(1.1), 1);
+      assert.strictEqual(_.toLength(MAX_INTEGER), MAX_ARRAY_LENGTH);
+    });
+
+    QUnit.test('should return `value` if a valid length', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.toLength(0), 0);
+      assert.strictEqual(_.toLength(3), 3);
+      assert.strictEqual(_.toLength(MAX_ARRAY_LENGTH), MAX_ARRAY_LENGTH);
+    });
+
+    QUnit.test('should convert `-0` to `0`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(1 / _.toLength(-0), Infinity);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('number coercion methods');
+
+  lodashStable.each(['toInteger', 'toNumber', 'toSafeInteger'], function(methodName) {
+    var func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should preserve the sign of `0`', function(assert) {
+      assert.expect(2);
+
+      var values = [0, '0', -0, '-0'],
+          expected = [[0, Infinity], [0, Infinity], [-0, -Infinity], [-0, -Infinity]];
+
+      lodashStable.times(2, function(index) {
+        var others = lodashStable.map(values, index ? Object : identity);
+
+        var actual = lodashStable.map(others, function(value) {
+          var result = func(value);
+          return [result, 1 / result];
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+  });
+
+  lodashStable.each(['toInteger', 'toLength', 'toNumber', 'toSafeInteger'], function(methodName) {
+    var func = _[methodName],
+        isToLength = methodName == 'toLength',
+        isToNumber = methodName == 'toNumber',
+        isToSafeInteger = methodName == 'toSafeInteger';
+
+    function negative(string) {
+      return '-' + string;
+    }
+
+    function pad(string) {
+      return whitespace + string + whitespace;
+    }
+
+    function positive(string) {
+      return '+' + string;
+    }
+
+    QUnit.test('`_.' + methodName + '` should pass thru primitive number values', function(assert) {
+      assert.expect(1);
+
+      var values = [0, 1, NaN];
+
+      var expected = lodashStable.map(values, function(value) {
+        return (!isToNumber && value !== value) ? 0 : value;
+      });
+
+      var actual = lodashStable.map(values, func);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert number primitives and objects to numbers', function(assert) {
+      assert.expect(1);
+
+      var values = [2, 1.2, MAX_SAFE_INTEGER, MAX_INTEGER, Infinity, NaN];
+
+      var expected = lodashStable.map(values, function(value) {
+        if (!isToNumber) {
+          if (value == 1.2) {
+            value = 1;
+          }
+          else if (value == Infinity) {
+            value = MAX_INTEGER;
+          }
+          else if (value !== value) {
+            value = 0;
+          }
+          if (isToLength || isToSafeInteger) {
+            value = Math.min(value, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
+          }
+        }
+        var neg = isToLength ? 0 : -value;
+        return [value, value, neg, neg];
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        return [func(value), func(Object(value)), func(-value), func(Object(-value))];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert string primitives and objects to numbers', function(assert) {
+      assert.expect(1);
+
+      var transforms = [identity, pad, positive, negative];
+
+      var values = [
+        '10', '1.234567890', (MAX_SAFE_INTEGER + ''),
+        '1e+308', '1e308', '1E+308', '1E308',
+        '5e-324', '5E-324',
+        'Infinity', 'NaN'
+      ];
+
+      var expected = lodashStable.map(values, function(value) {
+        var n = +value;
+        if (!isToNumber) {
+          if (n == 1.234567890) {
+            n = 1;
+          }
+          else if (n == Infinity) {
+            n = MAX_INTEGER;
+          }
+          else if (n == Number.MIN_VALUE || n !== n) {
+            n = 0;
+          }
+          if (isToLength || isToSafeInteger) {
+            n = Math.min(n, isToLength ? MAX_ARRAY_LENGTH : MAX_SAFE_INTEGER);
+          }
+        }
+        var neg = isToLength ? 0 : -n;
+        return [n, n, n, n, n, n, neg, neg];
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        return lodashStable.flatMap(transforms, function(mod) {
+          return [func(mod(value)), func(Object(mod(value)))];
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert binary/octal strings to numbers', function(assert) {
+      assert.expect(1);
+
+      var numbers = [42, 5349, 1715004],
+          transforms = [identity, pad],
+          values = ['0b101010', '0o12345', '0x1a2b3c'];
+
+      var expected = lodashStable.map(numbers, function(n) {
+        return lodashStable.times(8, lodashStable.constant(n));
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        var upper = value.toUpperCase();
+        return lodashStable.flatMap(transforms, function(mod) {
+          return [func(mod(value)), func(Object(mod(value))), func(mod(upper)), func(Object(mod(upper)))];
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert invalid binary/octal strings to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
+      assert.expect(1);
+
+      var transforms = [identity, pad, positive, negative],
+          values = ['0b', '0o', '0x', '0b1010102', '0o123458', '0x1a2b3x'];
+
+      var expected = lodashStable.map(values, function(n) {
+        return lodashStable.times(8, lodashStable.constant(isToNumber ? NaN : 0));
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        return lodashStable.flatMap(transforms, function(mod) {
+          return [func(mod(value)), func(Object(mod(value)))];
+        });
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert symbols to `' + (isToNumber ? 'NaN' : '0') + '`', function(assert) {
+      assert.expect(1);
+
+      if (Symbol) {
+        var object1 = Object(symbol),
+            object2 = Object(symbol),
+            values = [symbol, object1, object2],
+            expected = lodashStable.map(values, lodashStable.constant(isToNumber ? NaN : 0));
+
+        object2.valueOf = undefined;
+        var actual = lodashStable.map(values, func);
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should convert empty values to `0` or `NaN`', function(assert) {
+      assert.expect(1);
+
+      var values = falsey.concat(whitespace);
+
+      var expected = lodashStable.map(values, function(value) {
+        return (isToNumber && value !== whitespace) ? Number(value) : 0;
+      });
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? func(value) : func();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce objects to numbers', function(assert) {
+      assert.expect(1);
+
+      var values = [
+        {},
+        [],
+        [1],
+        [1, 2],
+        { 'valueOf': '1.1' },
+        { 'valueOf': '1.1', 'toString': lodashStable.constant('2.2') },
+        { 'valueOf': lodashStable.constant('1.1'), 'toString': '2.2' },
+        { 'valueOf': lodashStable.constant('1.1'), 'toString': lodashStable.constant('2.2') },
+        { 'valueOf': lodashStable.constant('-0x1a2b3c') },
+        { 'toString': lodashStable.constant('-0x1a2b3c') },
+        { 'valueOf': lodashStable.constant('0o12345') },
+        { 'toString': lodashStable.constant('0o12345') },
+        { 'valueOf': lodashStable.constant('0b101010') },
+        { 'toString': lodashStable.constant('0b101010') }
+      ];
+
+      var expected = [
+        NaN,   0,   1,   NaN,
+        NaN,  2.2,  1.1, 1.1,
+        NaN,  NaN,
+        5349, 5349,
+        42,   42
+      ];
+
+      if (!isToNumber) {
+        expected = [
+          0, 0, 1, 0,
+          0, 2, 1, 1,
+          0, 0,
+          5349, 5349,
+          42, 42
+        ];
+      }
+      var actual = lodashStable.map(values, func);
+
+      assert.deepEqual(actual, expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toPairs');
+
+  (function() {
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.entries, _.toPairs);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toPairsIn');
+
+  (function() {
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.entriesIn, _.toPairsIn);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('toPairs methods');
+
+  lodashStable.each(['toPairs', 'toPairsIn'], function(methodName) {
+    var func = _[methodName],
+        isToPairs = methodName == 'toPairs';
+
+    QUnit.test('`_.' + methodName + '` should create an array of string keyed-value pairs', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2 },
+          actual = lodashStable.sortBy(func(object), 0);
+
+      assert.deepEqual(actual, [['a', 1], ['b', 2]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
+      assert.expect(1);
+
+      var object = { '0': 'a', '1': 'b', 'length': 2 },
+          actual = lodashStable.sortBy(func(object), 0);
+
+      assert.deepEqual(actual, [['0', 'a'], ['1', 'b'], ['length', 2]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isToPairs ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var expected = isToPairs ? [['a', 1]] : [['a', 1], ['b', 2]],
+          actual = lodashStable.sortBy(func(new Foo), 0);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with strings', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each(['xo', Object('xo')], function(string) {
+        var actual = lodashStable.sortBy(func(string), 0);
+        assert.deepEqual(actual, [['0', 'x'], ['1', 'o']]);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toPath');
+
+  (function() {
+    QUnit.test('should convert a string to a path', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.toPath('a.b.c'), ['a', 'b', 'c']);
+      assert.deepEqual(_.toPath('a[0].b.c'), ['a', '0', 'b', 'c']);
+    });
+
+    QUnit.test('should coerce array elements to strings', function(assert) {
+      assert.expect(4);
+
+      var array = ['a', 'b', 'c'];
+
+      lodashStable.each([array, lodashStable.map(array, Object)], function(value) {
+        var actual = _.toPath(value);
+        assert.deepEqual(actual, array);
+        assert.notStrictEqual(actual, array);
+      });
+    });
+
+    QUnit.test('should a new path array', function(assert) {
+      assert.expect(1);
+
+      assert.notStrictEqual(_.toPath('a.b.c'), _.toPath('a.b.c'));
+    });
+
+    QUnit.test('should not coerce symbols to strings', function(assert) {
+      assert.expect(4);
+
+      if (Symbol) {
+        var object = Object(symbol);
+        lodashStable.each([symbol, object, [symbol], [object]], function(value) {
+          var actual = _.toPath(value);
+          assert.ok(lodashStable.isSymbol(actual[0]));
+        });
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should handle complex paths', function(assert) {
+      assert.expect(1);
+
+      var actual = _.toPath('a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g');
+      assert.deepEqual(actual, ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']);
+    });
+
+    QUnit.test('should ignore consecutive brackets and dots', function(assert) {
+      assert.expect(4);
+
+      var expected = ['a'];
+      assert.deepEqual(_.toPath('a.'), expected);
+      assert.deepEqual(_.toPath('a[]'), expected);
+
+      expected = ['a', 'b'];
+      assert.deepEqual(_.toPath('a..b'), expected);
+      assert.deepEqual(_.toPath('a[][]b'), expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toPlainObject');
+
+  (function() {
+    var args = arguments;
+
+    QUnit.test('should flatten inherited string keyed properties', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.b = 2;
+      }
+      Foo.prototype.c = 3;
+
+      var actual = lodashStable.assign({ 'a': 1 }, _.toPlainObject(new Foo));
+      assert.deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
+    });
+
+    QUnit.test('should convert `arguments` objects to plain objects', function(assert) {
+      assert.expect(1);
+
+      var actual = _.toPlainObject(args),
+          expected = { '0': 1, '1': 2, '2': 3 };
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should convert arrays to plain objects', function(assert) {
+      assert.expect(1);
+
+      var actual = _.toPlainObject(['a', 'b', 'c']),
+          expected = { '0': 'a', '1': 'b', '2': 'c' };
+
+      assert.deepEqual(actual, expected);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.toString');
+
+  (function() {
+    QUnit.test('should treat nullish values as empty strings', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysEmptyString);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.toString(value) : _.toString();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var values = [-0, Object(-0), 0, Object(0)],
+          expected = ['-0', '-0', '0', '0'],
+          actual = lodashStable.map(values, _.toString);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not error on symbols', function(assert) {
+      assert.expect(1);
+
+      if (Symbol) {
+        try {
+          assert.strictEqual(_.toString(symbol), 'Symbol(a)');
+        } catch (e) {
+          assert.ok(false, e.message);
+        }
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should return the `toString` result of the wrapped value', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _([1, 2, 3]);
+        assert.strictEqual(wrapped.toString(), '1,2,3');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.transform');
+
+  (function() {
+    function Foo() {
+      this.a = 1;
+      this.b = 2;
+      this.c = 3;
+    }
+
+    QUnit.test('should create an object with the same `[[Prototype]]` as `object` when `accumulator` is nullish', function(assert) {
+      assert.expect(4);
+
+      var accumulators = [, null, undefined],
+          object = new Foo,
+          expected = lodashStable.map(accumulators, alwaysTrue);
+
+      var iteratee = function(result, value, key) {
+        result[key] = square(value);
+      };
+
+      var mapper = function(accumulator, index) {
+        return index ? _.transform(object, iteratee, accumulator) : _.transform(object, iteratee);
+      };
+
+      var results = lodashStable.map(accumulators, mapper);
+
+      var actual = lodashStable.map(results, function(result) {
+        return result instanceof Foo;
+      });
+
+      assert.deepEqual(actual, expected);
+
+      expected = lodashStable.map(accumulators, lodashStable.constant({ 'a': 1, 'b': 4, 'c': 9 }));
+      actual = lodashStable.map(results, lodashStable.toPlainObject);
+
+      assert.deepEqual(actual, expected);
+
+      object = { 'a': 1, 'b': 2, 'c': 3 };
+      actual = lodashStable.map(accumulators, mapper);
+
+      assert.deepEqual(actual, expected);
+
+      object = [1, 2, 3];
+      expected = lodashStable.map(accumulators, lodashStable.constant([1, 4, 9]));
+      actual = lodashStable.map(accumulators, mapper);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should create regular arrays from typed arrays', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(typedArrays, alwaysTrue);
+
+      var actual = lodashStable.map(typedArrays, function(type) {
+        var Ctor = root[type],
+            array = Ctor ? new Ctor(new ArrayBuffer(24)) : [];
+
+        return lodashStable.isArray(_.transform(array, noop));
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should support an `accumulator` value', function(assert) {
+      assert.expect(6);
+
+      var values = [new Foo, [1, 2, 3], { 'a': 1, 'b': 2, 'c': 3 }],
+          expected = lodashStable.map(values, lodashStable.constant([1, 4, 9]));
+
+      var actual = lodashStable.map(values, function(value) {
+        return _.transform(value, function(result, value) {
+          result.push(square(value));
+        }, []);
+      });
+
+      assert.deepEqual(actual, expected);
+
+      var object = { 'a': 1, 'b': 4, 'c': 9 },
+      expected = [object, { '0': 1, '1': 4, '2': 9 }, object];
+
+      actual = lodashStable.map(values, function(value) {
+        return _.transform(value, function(result, value, key) {
+          result[key] = square(value);
+        }, {});
+      });
+
+      assert.deepEqual(actual, expected);
+
+      lodashStable.each([[], {}], function(accumulator) {
+        var actual = lodashStable.map(values, function(value) {
+          return _.transform(value, noop, accumulator);
+        });
+
+        assert.ok(lodashStable.every(actual, function(result) {
+          return result === accumulator;
+        }));
+
+        assert.strictEqual(_.transform(null, null, accumulator), accumulator);
+      });
+    });
+
+    QUnit.test('should treat sparse arrays as dense', function(assert) {
+      assert.expect(1);
+
+      var actual = _.transform(Array(1), function(result, value, index) {
+        result[index] = String(value);
+      });
+
+      assert.deepEqual(actual, ['undefined']);
+    });
+
+    QUnit.test('should work without an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      assert.ok(_.transform(new Foo) instanceof Foo);
+    });
+
+    QUnit.test('should ensure `object` is an object before using its `[[Prototype]]`', function(assert) {
+      assert.expect(2);
+
+      var Ctors = [Boolean, Boolean, Number, Number, Number, String, String],
+          values = [false, true, 0, 1, NaN, '', 'a'],
+          expected = lodashStable.map(values, alwaysEmptyObject);
+
+      var results = lodashStable.map(values, function(value) {
+        return _.transform(value);
+      });
+
+      assert.deepEqual(results, expected);
+
+      expected = lodashStable.map(values, alwaysFalse);
+
+      var actual = lodashStable.map(results, function(value, index) {
+        return value instanceof Ctors[index];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should ensure `object` constructor is a function before using its `[[Prototype]]`', function(assert) {
+      assert.expect(1);
+
+      Foo.prototype.constructor = null;
+      assert.notOk(_.transform(new Foo) instanceof Foo);
+      Foo.prototype.constructor = Foo;
+    });
+
+    QUnit.test('should create an empty object when given a falsey `object` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyObject);
+
+      var actual = lodashStable.map(falsey, function(object, index) {
+        return index ? _.transform(object) : _.transform();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    lodashStable.each({
+      'array': [1, 2, 3],
+      'object': { 'a': 1, 'b': 2, 'c': 3 }
+    },
+    function(object, key) {
+      QUnit.test('should provide the correct `iteratee` arguments when transforming an ' + key, function(assert) {
+        assert.expect(2);
+
+        var args;
+
+        _.transform(object, function() {
+          args || (args = slice.call(arguments));
+        });
+
+        var first = args[0];
+        if (key == 'array') {
+          assert.ok(first !== object && lodashStable.isArray(first));
+          assert.deepEqual(args, [first, 1, 0, object]);
+        } else {
+          assert.ok(first !== object && lodashStable.isPlainObject(first));
+          assert.deepEqual(args, [first, 1, 'a', object]);
+        }
+      });
+    });
+
+    QUnit.test('should create an object from the same realm as `object`', function(assert) {
+      assert.expect(1);
+
+      var objects = lodashStable.filter(realm, function(value) {
+        return lodashStable.isObject(value) && !lodashStable.isElement(value);
+      });
+
+      var expected = lodashStable.map(objects, alwaysTrue);
+
+      var actual = lodashStable.map(objects, function(object) {
+        var Ctor = object.constructor,
+            result = _.transform(object);
+
+        if (result === object) {
+          return false;
+        }
+        if (lodashStable.isTypedArray(object)) {
+          return result instanceof Array;
+        }
+        return result instanceof Ctor || !(new Ctor instanceof Ctor);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('trim methods');
+
+  lodashStable.each(['trim', 'trimStart', 'trimEnd'], function(methodName, index) {
+    var func = _[methodName],
+        parts = [];
+
+    if (index != 2) {
+      parts.push('leading');
+    }
+    if (index != 1) {
+      parts.push('trailing');
+    }
+    parts = parts.join(' and ');
+
+    QUnit.test('`_.' + methodName + '` should remove ' + parts + ' whitespace', function(assert) {
+      assert.expect(1);
+
+      var string = whitespace + 'a b c' + whitespace,
+          expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
+
+      assert.strictEqual(func(string), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `string` to a string', function(assert) {
+      assert.expect(1);
+
+      var object = { 'toString': lodashStable.constant(whitespace + 'a b c' + whitespace) },
+          expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
+
+      assert.strictEqual(func(object), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should remove ' + parts + ' `chars`', function(assert) {
+      assert.expect(1);
+
+      var string = '-_-a-b-c-_-',
+          expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
+
+      assert.strictEqual(func(string, '_-'), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should coerce `chars` to a string', function(assert) {
+      assert.expect(1);
+
+      var object = { 'toString': lodashStable.constant('_-') },
+          string = '-_-a-b-c-_-',
+          expected = (index == 2 ? '-_-' : '') + 'a-b-c' + (index == 1 ? '-_-' : '');
+
+      assert.strictEqual(func(string, object), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an empty string for empty values and `chars`', function(assert) {
+      assert.expect(6);
+
+      lodashStable.each([null, '_-'], function(chars) {
+        assert.strictEqual(func(null, chars), '');
+        assert.strictEqual(func(undefined, chars), '');
+        assert.strictEqual(func('', chars), '');
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `undefined` or empty string values for `chars`', function(assert) {
+      assert.expect(2);
+
+      var string = whitespace + 'a b c' + whitespace,
+          expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
+
+      assert.strictEqual(func(string, undefined), expected);
+      assert.strictEqual(func(string, ''), string);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var string = Object(whitespace + 'a b c' + whitespace),
+          trimmed = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : ''),
+          actual = lodashStable.map([string, string, string], func);
+
+      assert.deepEqual(actual, [trimmed, trimmed, trimmed]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var string = whitespace + 'a b c' + whitespace,
+            expected = (index == 2 ? whitespace : '') + 'a b c' + (index == 1 ? whitespace : '');
+
+        assert.strictEqual(_(string)[methodName](), expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var string = whitespace + 'a b c' + whitespace;
+        assert.ok(_(string).chain()[methodName]() instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('uncommon symbols');
+
+  (function() {
+    var flag = '\ud83c\uddfa\ud83c\uddf8',
+        heart = '\u2764' + emojiVar,
+        hearts = '\ud83d\udc95',
+        comboGlyph = '\ud83d\udc68\u200d' + heart + '\u200d\ud83d\udc8B\u200d\ud83d\udc68',
+        hashKeycap = '#' + emojiVar + '\u20e3',
+        leafs = '\ud83c\udf42',
+        mic = '\ud83c\udf99',
+        noMic = mic + '\u20e0',
+        raisedHand = '\u270B' + emojiVar,
+        rocket = '\ud83d\ude80',
+        thumbsUp = '\ud83d\udc4d';
+
+    QUnit.test('should account for astral symbols', function(assert) {
+      assert.expect(34);
+
+      var allHearts = _.repeat(hearts, 10),
+          chars = hearts + comboGlyph,
+          string = 'A ' + leafs + ', ' + comboGlyph + ', and ' + rocket,
+          trimChars = comboGlyph + hearts,
+          trimString = trimChars + string + trimChars;
+
+      assert.strictEqual(_.camelCase(hearts + ' the ' + leafs), hearts + 'The' + leafs);
+      assert.strictEqual(_.camelCase(string), 'a' + leafs + comboGlyph + 'And' + rocket);
+      assert.strictEqual(_.capitalize(rocket), rocket);
+
+      assert.strictEqual(_.pad(string, 16), ' ' + string + '  ');
+      assert.strictEqual(_.padStart(string, 16), '   ' + string);
+      assert.strictEqual(_.padEnd(string, 16), string + '   ');
+
+      assert.strictEqual(_.pad(string, 16, chars), hearts + string + chars);
+      assert.strictEqual(_.padStart(string, 16, chars), chars + hearts + string);
+      assert.strictEqual(_.padEnd(string, 16, chars), string + chars + hearts);
+
+      assert.strictEqual(_.size(string), 13);
+      assert.deepEqual(_.split(string, ' '), ['A', leafs + ',', comboGlyph + ',', 'and', rocket]);
+      assert.deepEqual(_.split(string, ' ', 3), ['A', leafs + ',', comboGlyph + ',']);
+      assert.deepEqual(_.split(string, undefined), [string]);
+      assert.deepEqual(_.split(string, undefined, -1), [string]);
+      assert.deepEqual(_.split(string, undefined, 0), []);
+
+      var expected = ['A', ' ', leafs, ',', ' ', comboGlyph, ',', ' ', 'a', 'n', 'd', ' ', rocket];
+
+      assert.deepEqual(_.split(string, ''), expected);
+      assert.deepEqual(_.split(string, '', 6), expected.slice(0, 6));
+      assert.deepEqual(_.toArray(string), expected);
+
+      assert.strictEqual(_.trim(trimString, chars), string);
+      assert.strictEqual(_.trimStart(trimString, chars), string + trimChars);
+      assert.strictEqual(_.trimEnd(trimString, chars), trimChars + string);
+
+      assert.strictEqual(_.truncate(string, { 'length': 13 }), string);
+      assert.strictEqual(_.truncate(string, { 'length': 6 }), 'A ' + leafs + '...');
+
+      assert.deepEqual(_.words(string), ['A', leafs, comboGlyph, 'and', rocket]);
+      assert.deepEqual(_.toArray(hashKeycap), [hashKeycap]);
+      assert.deepEqual(_.toArray(noMic), [noMic]);
+
+      lodashStable.times(2, function(index) {
+        var separator = index ? RegExp(hearts) : hearts,
+            options = { 'length': 4, 'separator': separator },
+            actual = _.truncate(string, options);
+
+        assert.strictEqual(actual, 'A...');
+        assert.strictEqual(actual.length, 4);
+
+        actual = _.truncate(allHearts, options);
+        assert.strictEqual(actual, hearts + '...');
+        assert.strictEqual(actual.length, 5);
+      });
+    });
+
+    QUnit.test('should account for combining diacritical marks', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.map(comboMarks, function(mark) {
+        return 'o' + mark;
+      });
+
+      var expected = lodashStable.map(values, function(value) {
+        return [1, [value], [value]];
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        return [_.size(value), _.toArray(value), _.words(value)];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should account for fitzpatrick modifiers', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.map(fitzModifiers, function(modifier) {
+        return thumbsUp + modifier;
+      });
+
+      var expected = lodashStable.map(values, function(value) {
+        return [1, [value], [value]];
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        return [_.size(value), _.toArray(value), _.words(value)];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should account for regional symbols', function(assert) {
+      assert.expect(6);
+
+      var pair = flag.match(/\ud83c[\udde6-\uddff]/g),
+          regionals = pair.join(' ');
+
+      assert.strictEqual(_.size(flag), 1);
+      assert.strictEqual(_.size(regionals), 3);
+
+      assert.deepEqual(_.toArray(flag), [flag]);
+      assert.deepEqual(_.toArray(regionals), [pair[0], ' ', pair[1]]);
+
+      assert.deepEqual(_.words(flag), [flag]);
+      assert.deepEqual(_.words(regionals), [pair[0], pair[1]]);
+    });
+
+    QUnit.test('should account for variation selectors', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.size(heart), 1);
+      assert.deepEqual(_.toArray(heart), [heart]);
+      assert.deepEqual(_.words(heart), [heart]);
+    });
+
+    QUnit.test('should account for variation selectors with fitzpatrick modifiers', function(assert) {
+      assert.expect(1);
+
+      var values = lodashStable.map(fitzModifiers, function(modifier) {
+        return raisedHand + modifier;
+      });
+
+      var expected = lodashStable.map(values, function(value) {
+        return [1, [value], [value]];
+      });
+
+      var actual = lodashStable.map(values, function(value) {
+        return [_.size(value), _.toArray(value), _.words(value)];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should match lone surrogates', function(assert) {
+      assert.expect(3);
+
+      var pair = hearts.split(''),
+          surrogates = pair[0] + ' ' + pair[1];
+
+      assert.strictEqual(_.size(surrogates), 3);
+      assert.deepEqual(_.toArray(surrogates), [pair[0], ' ', pair[1]]);
+      assert.deepEqual(_.words(surrogates), []);
+    });
+
+    QUnit.test('should match side by side fitzpatrick modifiers separately ', function(assert) {
+      assert.expect(1);
+
+      var string = fitzModifiers[0] + fitzModifiers[0];
+      assert.deepEqual(_.toArray(string), [fitzModifiers[0], fitzModifiers[0]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unary');
+
+  (function() {
+    function fn() {
+      return slice.call(arguments);
+    }
+
+    QUnit.test('should cap the number of arguments provided to `func`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(['6', '8', '10'], _.unary(parseInt));
+      assert.deepEqual(actual, [6, 8, 10]);
+    });
+
+    QUnit.test('should work when provided less than the capped number of arguments', function(assert) {
+      assert.expect(1);
+
+      var capped = _.unary(fn);
+      assert.deepEqual(capped(), []);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unescape');
+
+  (function() {
+    var escaped = '&amp;&lt;&gt;&quot;&#39;\/',
+        unescaped = '&<>"\'\/';
+
+    escaped += escaped;
+    unescaped += unescaped;
+
+    QUnit.test('should unescape entities in order', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.unescape('&amp;lt;'), '&lt;');
+    });
+
+    QUnit.test('should unescape the proper entities', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.unescape(escaped), unescaped);
+    });
+
+    QUnit.test('should not unescape the "&#x2F;" entity', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.unescape('&#x2F;'), '&#x2F;');
+    });
+
+    QUnit.test('should handle strings with nothing to unescape', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.unescape('abc'), 'abc');
+    });
+
+    QUnit.test('should unescape the same characters escaped by `_.escape`', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(_.unescape(_.escape(unescaped)), unescaped);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unionBy');
+
+  (function() {
+    QUnit.test('should accept an `iteratee` argument', function(assert) {
+      assert.expect(2);
+
+      var actual = _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+      assert.deepEqual(actual, [2.1, 1.2, 4.3]);
+
+      actual = _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+      assert.deepEqual(actual, [{ 'x': 1 }, { 'x': 2 }]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.unionBy([2.1, 1.2], [4.3, 2.4], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [2.1]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unionWith');
+
+  (function() {
+    QUnit.test('should work with a `comparator` argument', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
+          others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
+          actual = _.unionWith(objects, others, lodashStable.isEqual);
+
+      assert.deepEqual(actual, [objects[0], objects[1], others[0]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('union methods');
+
+  lodashStable.each(['union', 'unionBy', 'unionWith'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return the union of the given arrays', function(assert) {
+      assert.expect(1);
+
+      var actual = func([1, 3, 2], [5, 2, 1, 4], [2, 1]);
+      assert.deepEqual(actual, [1, 3, 2, 5, 4]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should not flatten nested arrays', function(assert) {
+      assert.expect(1);
+
+      var actual = func([1, 3, 2], [1, [5]], [2, [4]]);
+      assert.deepEqual(actual, [1, 3, 2, [5], [4]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
+      assert.expect(3);
+
+      var array = [0];
+      assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
+      assert.deepEqual(func(null, array, null, [2, 1]), [0, 2, 1]);
+      assert.deepEqual(func(array, null, args, null), [0, 1, 2, 3]);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.uniq');
+
+  (function() {
+    QUnit.test('should perform an unsorted uniq when used as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var array = [[2, 1, 2], [1, 2, 1]],
+          actual = lodashStable.map(array, lodashStable.uniq);
+
+      assert.deepEqual(actual, [[2, 1], [1, 2]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('uniqBy methods');
+
+  lodashStable.each(['uniqBy', 'sortedUniqBy'], function(methodName) {
+    var func = _[methodName],
+        isSorted = methodName == 'sortedUniqBy',
+        objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
+
+    if (isSorted) {
+      objects = _.sortBy(objects, 'a');
+    }
+    QUnit.test('`_.' + methodName + '` should work with an `iteratee` argument', function(assert) {
+      assert.expect(1);
+
+      var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3);
+
+      var actual = func(objects, function(object) {
+        return object.a;
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should work with large arrays', function(assert) {
+      assert.expect(2);
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function() {
+        return [1, 2];
+      });
+
+      var actual = func(largeArray, String);
+
+      assert.deepEqual(actual, [[1, 2]]);
+      assert.strictEqual(actual[0], largeArray[0]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      func(objects, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [objects[0]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `_.property` shorthands', function(assert) {
+      assert.expect(2);
+
+      var expected = isSorted ? [{ 'a': 1 }, { 'a': 2 }, { 'a': 3 }] : objects.slice(0, 3),
+          actual = func(objects, 'a');
+
+      assert.deepEqual(actual, expected);
+
+      var arrays = [[2], [3], [1], [2], [3], [1]];
+      if (isSorted) {
+        arrays = lodashStable.sortBy(arrays, 0);
+      }
+      expected = isSorted ? [[1], [2], [3]] : arrays.slice(0, 3);
+      actual = func(arrays, 0);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    lodashStable.each({
+      'an array': [0, 'a'],
+      'an object': { '0': 'a' },
+      'a number': 0,
+      'a string': '0'
+    },
+    function(iteratee, key) {
+      QUnit.test('`_.' + methodName + '` should work with ' + key + ' for `iteratee`', function(assert) {
+        assert.expect(1);
+
+        var actual = func([['a'], ['a'], ['b']], iteratee);
+        assert.deepEqual(actual, [['a'], ['b']]);
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.uniqWith');
+
+  (function() {
+    QUnit.test('should work with a `comparator` argument', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 },  { 'x': 1, 'y': 2 }],
+          actual = _.uniqWith(objects, lodashStable.isEqual);
+
+      assert.deepEqual(actual, [objects[0], objects[1]]);
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
+        return isEven(index) ? -0 : 0;
+      });
+
+      var arrays = [[-0, 0], largeArray],
+          expected = lodashStable.map(arrays, lodashStable.constant(['-0']));
+
+      var actual = lodashStable.map(arrays, function(array) {
+        return lodashStable.map(_.uniqWith(array, lodashStable.eq), lodashStable.toString);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('uniq methods');
+
+  lodashStable.each(['uniq', 'uniqBy', 'uniqWith', 'sortedUniq', 'sortedUniqBy'], function(methodName) {
+    var func = _[methodName],
+        isSorted = /^sorted/.test(methodName),
+        objects = [{ 'a': 2 }, { 'a': 3 }, { 'a': 1 }, { 'a': 2 }, { 'a': 3 }, { 'a': 1 }];
+
+    if (isSorted) {
+      objects = _.sortBy(objects, 'a');
+    }
+    else {
+      QUnit.test('`_.' + methodName + '` should return unique values of an unsorted array', function(assert) {
+        assert.expect(1);
+
+        var array = [2, 3, 1, 2, 3, 1];
+        assert.deepEqual(func(array), [2, 3, 1]);
+      });
+    }
+    QUnit.test('`_.' + methodName + '` should return unique values of a sorted array', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 1, 2, 2, 3];
+      assert.deepEqual(func(array), [1, 2, 3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat object instances as unique', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(objects), objects);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat `-0` as `0`', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.map(func([-0, 0]), lodashStable.toString);
+      assert.deepEqual(actual, ['0']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should match `NaN`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func([NaN, NaN]), [NaN]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays', function(assert) {
+      assert.expect(1);
+
+      var largeArray = [],
+          expected = [0, {}, 'a'],
+          count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
+
+      lodashStable.each(expected, function(value) {
+        lodashStable.times(count, function() {
+          largeArray.push(value);
+        });
+      });
+
+      assert.deepEqual(func(largeArray), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of `-0` as `0`', function(assert) {
+      assert.expect(1);
+
+      var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, function(index) {
+        return isEven(index) ? -0 : 0;
+      });
+
+      var actual = lodashStable.map(func(largeArray), lodashStable.toString);
+      assert.deepEqual(actual, ['0']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of boolean, `NaN`, and nullish values', function(assert) {
+      assert.expect(1);
+
+      var largeArray = [],
+          expected = [null, undefined, false, true, NaN],
+          count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
+
+      lodashStable.each(expected, function(value) {
+        lodashStable.times(count, function() {
+          largeArray.push(value);
+        });
+      });
+
+      assert.deepEqual(func(largeArray), expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of symbols', function(assert) {
+      assert.expect(1);
+
+      if (Symbol) {
+        var largeArray = lodashStable.times(LARGE_ARRAY_SIZE, Symbol);
+        assert.deepEqual(func(largeArray), largeArray);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with large arrays of well-known symbols', function(assert) {
+      assert.expect(1);
+
+      // See http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols.
+      if (Symbol) {
+        var expected = [
+          Symbol.hasInstance, Symbol.isConcatSpreadable, Symbol.iterator,
+          Symbol.match, Symbol.replace, Symbol.search, Symbol.species,
+          Symbol.split, Symbol.toPrimitive, Symbol.toStringTag, Symbol.unscopables
+        ];
+
+        var largeArray = [],
+            count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
+
+        expected = lodashStable.map(expected, function(symbol) {
+          return symbol || {};
+        });
+
+        lodashStable.each(expected, function(value) {
+          lodashStable.times(count, function() {
+            largeArray.push(value);
+          });
+        });
+
+        assert.deepEqual(func(largeArray), expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should distinguish between numbers and numeric strings', function(assert) {
+      assert.expect(1);
+
+      var largeArray = [],
+          expected = ['2', 2, Object('2'), Object(2)],
+          count = Math.ceil(LARGE_ARRAY_SIZE / expected.length);
+
+      lodashStable.each(expected, function(value) {
+        lodashStable.times(count, function() {
+          largeArray.push(value);
+        });
+      });
+
+      assert.deepEqual(func(largeArray), expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.uniqueId');
+
+  (function() {
+    QUnit.test('should generate unique ids', function(assert) {
+      assert.expect(1);
+
+      var actual = lodashStable.times(1000, function(assert) {
+        return _.uniqueId();
+      });
+
+      assert.strictEqual(lodashStable.uniq(actual).length, actual.length);
+    });
+
+    QUnit.test('should return a string value when not providing a prefix argument', function(assert) {
+      assert.expect(1);
+
+      assert.strictEqual(typeof _.uniqueId(), 'string');
+    });
+
+    QUnit.test('should coerce the prefix argument to a string', function(assert) {
+      assert.expect(1);
+
+      var actual = [_.uniqueId(3), _.uniqueId(2), _.uniqueId(1)];
+      assert.ok(/3\d+,2\d+,1\d+/.test(actual));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unset');
+
+  (function() {
+    QUnit.test('should unset property values', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a', ['a']], function(path) {
+        var object = { 'a': 1, 'c': 2 };
+        assert.strictEqual(_.unset(object, path), true);
+        assert.deepEqual(object, { 'c': 2 });
+      });
+    });
+
+    QUnit.test('should preserve the sign of `0`', function(assert) {
+      assert.expect(1);
+
+      var props = [-0, Object(-0), 0, Object(0)],
+          expected = lodashStable.map(props, lodashStable.constant([true, false]));
+
+      var actual = lodashStable.map(props, function(key) {
+        var object = { '-0': 'a', '0': 'b' };
+        return [_.unset(object, key), lodashStable.toString(key) in object];
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should unset symbol keyed property values', function(assert) {
+      assert.expect(2);
+
+      if (Symbol) {
+        var object = {};
+        object[symbol] = 1;
+
+        assert.strictEqual(_.unset(object, symbol), true);
+        assert.notOk(symbol in object);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should unset deep property values', function(assert) {
+      assert.expect(4);
+
+      lodashStable.each(['a.b', ['a', 'b']], function(path) {
+        var object = { 'a': { 'b': null } };
+        assert.strictEqual(_.unset(object, path), true);
+        assert.deepEqual(object, { 'a': {} });
+      });
+    });
+
+    QUnit.test('should handle complex paths', function(assert) {
+      assert.expect(4);
+
+      var paths = [
+        'a[-1.23]["[\\"b\\"]"].c[\'[\\\'d\\\']\'][\ne\n][f].g',
+        ['a', '-1.23', '["b"]', 'c', "['d']", '\ne\n', 'f', 'g']
+      ];
+
+      lodashStable.each(paths, function(path) {
+        var object = { 'a': { '-1.23': { '["b"]': { 'c': { "['d']": { '\ne\n': { 'f': { 'g': 8 } } } } } } } };
+        assert.strictEqual(_.unset(object, path), true);
+        assert.notOk('g' in object.a[-1.23]['["b"]'].c["['d']"]['\ne\n'].f);
+      });
+    });
+
+    QUnit.test('should return `true` for nonexistent paths', function(assert) {
+      assert.expect(5);
+
+      var object = { 'a': { 'b': { 'c': null } } };
+
+      lodashStable.each(['z', 'a.z', 'a.b.z', 'a.b.c.z'], function(path) {
+        assert.strictEqual(_.unset(object, path), true);
+      });
+
+      assert.deepEqual(object, { 'a': { 'b': { 'c': null } } });
+    });
+
+    QUnit.test('should not error when `object` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [null, undefined],
+          expected = [[true, true], [true, true]];
+
+      var actual = lodashStable.map(values, function(value) {
+        try {
+          return [_.unset(value, 'a.b'), _.unset(value, ['a', 'b'])];
+        } catch (e) {
+          return e.message;
+        }
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should follow `path` over non-plain objects', function(assert) {
+      assert.expect(8);
+
+      var object = { 'a': '' },
+          paths = ['constructor.prototype.a', ['constructor', 'prototype', 'a']];
+
+      lodashStable.each(paths, function(path) {
+        numberProto.a = 1;
+
+        var actual = _.unset(0, path);
+        assert.strictEqual(actual, true);
+        assert.notOk('a' in numberProto);
+
+        delete numberProto.a;
+      });
+
+      lodashStable.each(['a.replace.b', ['a', 'replace', 'b']], function(path) {
+        stringProto.replace.b = 1;
+
+        var actual = _.unset(object, path);
+        assert.strictEqual(actual, true);
+        assert.notOk('a' in stringProto.replace);
+
+        delete stringProto.replace.b;
+      });
+    });
+
+    QUnit.test('should return `false` for non-configurable properties', function(assert) {
+      assert.expect(1);
+
+      var object = {};
+
+      if (!isStrict && defineProperty) {
+        defineProperty(object, 'a', {
+          'configurable': false,
+          'enumerable': true,
+          'writable': true,
+          'value': 1,
+        });
+        assert.strictEqual(_.unset(object, 'a'), false);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unzipWith');
+
+  (function() {
+    QUnit.test('should unzip arrays combining regrouped elements with `iteratee`', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 4], [2, 5], [3, 6]];
+
+      var actual = _.unzipWith(array, function(a, b, c) {
+        return a + b + c;
+      });
+
+      assert.deepEqual(actual, [6, 15]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.unzipWith([[1, 3, 5], [2, 4, 6]], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [1, 2]);
+    });
+
+    QUnit.test('should perform a basic unzip when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 3], [2, 4]],
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant(_.unzip(array)));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.unzipWith(array, value) : _.unzipWith(array);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.updateWith');
+
+  (function() {
+    QUnit.test('should work with a `customizer` callback', function(assert) {
+      assert.expect(1);
+
+      var actual = _.updateWith({ '0': {} }, '[0][1][2]', alwaysThree, function(value) {
+        return lodashStable.isObject(value) ? undefined : {};
+      });
+
+      assert.deepEqual(actual, { '0': { '1': { '2': 3 } } });
+    });
+
+    QUnit.test('should work with a `customizer` that returns `undefined`', function(assert) {
+      assert.expect(1);
+
+      var actual = _.updateWith({}, 'a[0].b.c', alwaysFour, noop);
+      assert.deepEqual(actual, { 'a': [{ 'b': { 'c': 4 } }] });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('update methods');
+
+  lodashStable.each(['update', 'updateWith'], function(methodName) {
+    var func = _[methodName],
+        oldValue = 1;
+
+    QUnit.test('`_.' + methodName + '` should invoke `updater` with the value on `path` of `object`', function(assert) {
+      assert.expect(4);
+
+      var object = { 'a': [{ 'b': { 'c': oldValue } }] },
+          expected = oldValue + 1;
+
+      lodashStable.each(['a[0].b.c', ['a', '0', 'b', 'c']], function(path) {
+        func(object, path, function(n) {
+          assert.strictEqual(n, oldValue);
+          return ++n;
+        });
+
+        assert.strictEqual(object.a[0].b.c, expected);
+        object.a[0].b.c = oldValue;
+      });
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.upperCase');
+
+  (function() {
+    QUnit.test('should uppercase as space-separated words', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.upperCase('--foo-bar--'), 'FOO BAR');
+      assert.strictEqual(_.upperCase('fooBar'), 'FOO BAR');
+      assert.strictEqual(_.upperCase('__foo_bar__'), 'FOO BAR');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.upperFirst');
+
+  (function() {
+    QUnit.test('should uppercase only the first character', function(assert) {
+      assert.expect(3);
+
+      assert.strictEqual(_.upperFirst('fred'), 'Fred');
+      assert.strictEqual(_.upperFirst('Fred'), 'Fred');
+      assert.strictEqual(_.upperFirst('FRED'), 'FRED');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('values methods');
+
+  lodashStable.each(['values', 'valuesIn'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        strictArgs = (function() { 'use strict'; return arguments; }(1, 2, 3)),
+        func = _[methodName],
+        isValues = methodName == 'values';
+
+    QUnit.test('`_.' + methodName + '` should get string keyed values of `object`', function(assert) {
+      assert.expect(1);
+
+      var object = { 'a': 1, 'b': 2 },
+          actual = func(object).sort();
+
+      assert.deepEqual(actual, [1, 2]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) {
+      assert.expect(1);
+
+      var object = { '0': 'a', '1': 'b', 'length': 2 },
+          actual = func(object).sort();
+
+      assert.deepEqual(actual, [2, 'a', 'b']);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + 'include inherited string keyed property values', function(assert) {
+      assert.expect(1);
+
+      function Foo() {
+        this.a = 1;
+      }
+      Foo.prototype.b = 2;
+
+      var expected = isValues ? [1] : [1, 2],
+          actual = func(new Foo).sort();
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      var values = [args, strictArgs],
+          expected = lodashStable.map(values, lodashStable.constant([1, 2, 3]));
+
+      var actual = lodashStable.map(values, function(value) {
+        return func(value).sort();
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.without');
+
+  (function() {
+    QUnit.test('should use strict equality to determine the values to reject', function(assert) {
+      assert.expect(2);
+
+      var object1 = { 'a': 1 },
+          object2 = { 'b': 2 },
+          array = [object1, object2];
+
+      assert.deepEqual(_.without(array, { 'a': 1 }), array);
+      assert.deepEqual(_.without(array, object1), [object2]);
+    });
+
+    QUnit.test('should remove all occurrences of each value from an array', function(assert) {
+      assert.expect(1);
+
+      var array = [1, 2, 3, 1, 2, 3];
+      assert.deepEqual(_.without(array, 1, 2), [3, 3]);
+    });
+  }(1, 2, 3));
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.words');
+
+  (function() {
+    QUnit.test('should treat latin-1 supplementary letters as words', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(burredLetters, function(letter) {
+        return [letter];
+      });
+
+      var actual = lodashStable.map(burredLetters, function(letter) {
+        return _.words(letter);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not treat mathematical operators as words', function(assert) {
+      assert.expect(1);
+
+      var operators = ['\xac', '\xb1', '\xd7', '\xf7'],
+          expected = lodashStable.map(operators, alwaysEmptyArray),
+          actual = lodashStable.map(operators, _.words);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not treat punctuation as words', function(assert) {
+      assert.expect(1);
+
+      var marks = [
+        '\u2012', '\u2013', '\u2014', '\u2015',
+        '\u2024', '\u2025', '\u2026',
+        '\u205d', '\u205e'
+      ];
+
+      var expected = lodashStable.map(marks, alwaysEmptyArray),
+          actual = lodashStable.map(marks, _.words);
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should support a `pattern` argument', function(assert) {
+      assert.expect(2);
+
+      assert.deepEqual(_.words('abcd', /ab|cd/g), ['ab', 'cd']);
+      assert.deepEqual(_.words('abcd', 'ab|cd'), ['ab']);
+    });
+
+    QUnit.test('should work with compound words', function(assert) {
+      assert.expect(12);
+
+      assert.deepEqual(_.words('12Feet'), ['12', 'Feet']);
+      assert.deepEqual(_.words('aeiouAreVowels'), ['aeiou', 'Are', 'Vowels']);
+      assert.deepEqual(_.words('enable 6h format'), ['enable', '6', 'h', 'format']);
+      assert.deepEqual(_.words('enable 24H format'), ['enable', '24', 'H', 'format']);
+      assert.deepEqual(_.words('isISO8601'), ['is', 'ISO', '8601']);
+      assert.deepEqual(_.words('LETTERSAeiouAreVowels'), ['LETTERS', 'Aeiou', 'Are', 'Vowels']);
+      assert.deepEqual(_.words('tooLegit2Quit'), ['too', 'Legit', '2', 'Quit']);
+      assert.deepEqual(_.words('walk500Miles'), ['walk', '500', 'Miles']);
+      assert.deepEqual(_.words('xhr2Request'), ['xhr', '2', 'Request']);
+      assert.deepEqual(_.words('XMLHttp'), ['XML', 'Http']);
+      assert.deepEqual(_.words('XmlHTTP'), ['Xml', 'HTTP']);
+      assert.deepEqual(_.words('XmlHttp'), ['Xml', 'Http']);
+    });
+
+    QUnit.test('should work with compound words containing diacritical marks', function(assert) {
+      assert.expect(3);
+
+      assert.deepEqual(_.words('LETTERSÆiouAreVowels'), ['LETTERS', 'Æiou', 'Are', 'Vowels']);
+      assert.deepEqual(_.words('æiouAreVowels'), ['æiou', 'Are', 'Vowels']);
+      assert.deepEqual(_.words('æiou2Consonants'), ['æiou', '2', 'Consonants']);
+    });
+
+    QUnit.test('should work with contractions', function(assert) {
+      assert.expect(2);
+
+      var postfixes = ['d', 'll', 'm', 're', 's', 't', 've'];
+
+      lodashStable.each(["'", '\u2019'], function(apos) {
+        var actual = lodashStable.map(postfixes, function(postfix) {
+          return _.words('a b' + apos + postfix +  ' c');
+        });
+
+        var expected = lodashStable.map(postfixes, function(postfix) {
+          return ['a', 'b' + apos + postfix, 'c'];
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+
+    QUnit.test('should work as an iteratee for methods like `_.map`', function(assert) {
+      assert.expect(1);
+
+      var strings = lodashStable.map(['a', 'b', 'c'], Object),
+          actual = lodashStable.map(strings, _.words);
+
+      assert.deepEqual(actual, [['a'], ['b'], ['c']]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.wrap');
+
+  (function() {
+    QUnit.test('should create a wrapped function', function(assert) {
+      assert.expect(1);
+
+      var p = _.wrap(_.escape, function(func, text) {
+        return '<p>' + func(text) + '</p>';
+      });
+
+      assert.strictEqual(p('fred, barney, & pebbles'), '<p>fred, barney, &amp; pebbles</p>');
+    });
+
+    QUnit.test('should provide the correct `wrapper` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      var wrapped = _.wrap(noop, function() {
+        args || (args = slice.call(arguments));
+      });
+
+      wrapped(1, 2, 3);
+      assert.deepEqual(args, [noop, 1, 2, 3]);
+    });
+
+    QUnit.test('should use `_.identity` when `wrapper` is nullish', function(assert) {
+      assert.expect(1);
+
+      var values = [, null, undefined],
+          expected = lodashStable.map(values, alwaysA);
+
+      var actual = lodashStable.map(values, function(value, index) {
+        var wrapped = index ? _.wrap('a', value) : _.wrap('a');
+        return wrapped('b', 'c');
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('should not set a `this` binding', function(assert) {
+      assert.expect(1);
+
+      var p = _.wrap(_.escape, function(func) {
+        return '<p>' + func(this.text) + '</p>';
+      });
+
+      var object = { 'p': p, 'text': 'fred, barney, & pebbles' };
+      assert.strictEqual(object.p(), '<p>fred, barney, &amp; pebbles</p>');
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('xor methods');
+
+  lodashStable.each(['xor', 'xorBy', 'xorWith'], function(methodName) {
+    var args = (function() { return arguments; }(1, 2, 3)),
+        func = _[methodName];
+
+    QUnit.test('`_.' + methodName + '` should return the symmetric difference of the given arrays', function(assert) {
+      assert.expect(1);
+
+      var actual = func([1, 2, 5], [2, 3, 5], [3, 4, 5]);
+      assert.deepEqual(actual, [1, 4, 5]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return an array of unique values', function(assert) {
+      assert.expect(2);
+
+      var actual = func([1, 1, 2, 5], [2, 2, 3, 5], [3, 4, 5, 5]);
+      assert.deepEqual(actual, [1, 4, 5]);
+
+      actual = func([1, 1]);
+      assert.deepEqual(actual, [1]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a new array when a single array is given', function(assert) {
+      assert.expect(1);
+
+      var array = [1];
+      assert.notStrictEqual(func(array), array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore individual secondary arguments', function(assert) {
+      assert.expect(1);
+
+      var array = [0];
+      assert.deepEqual(func(array, 3, null, { '0': 1 }), array);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
+      assert.expect(3);
+
+      var array = [1, 2];
+      assert.deepEqual(func(array, 3, { '0': 1 }, null), array);
+      assert.deepEqual(func(null, array, null, [2, 3]), [1, 3]);
+      assert.deepEqual(func(array, null, args, null), [3]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should return a wrapped value when chaining', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _([1, 2, 3])[methodName]([5, 2, 1, 4]);
+        assert.ok(wrapped instanceof _);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('`_.' + methodName + '` should work when in a lazy sequence before `head` or `last`', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE + 1),
+            wrapped = _(array).slice(1)[methodName]([LARGE_ARRAY_SIZE, LARGE_ARRAY_SIZE + 1]);
+
+        var actual = lodashStable.map(['head', 'last'], function(methodName) {
+          return wrapped[methodName]();
+        });
+
+        assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.xorBy');
+
+  (function() {
+    QUnit.test('should accept an `iteratee` argument', function(assert) {
+      assert.expect(2);
+
+      var actual = _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor);
+      assert.deepEqual(actual, [1.2, 4.3]);
+
+      actual = _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
+      assert.deepEqual(actual, [{ 'x': 2 }]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.xorBy([2.1, 1.2], [4.3, 2.4], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [4.3]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.xorWith');
+
+  (function() {
+    QUnit.test('should work with a `comparator` argument', function(assert) {
+      assert.expect(1);
+
+      var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }],
+          others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }],
+          actual = _.xorWith(objects, others, lodashStable.isEqual);
+
+      assert.deepEqual(actual, [objects[1], others[0]]);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('zipObject methods');
+
+  lodashStable.each(['zipObject', 'zipObjectDeep'], function(methodName) {
+    var func = _[methodName],
+        object = { 'barney': 36, 'fred': 40 },
+        isDeep = methodName == 'zipObjectDeep';
+
+    QUnit.test('`_.' + methodName + '` should zip together key/value arrays into an object', function(assert) {
+      assert.expect(1);
+
+      var actual = func(['barney', 'fred'], [36, 40]);
+      assert.deepEqual(actual, object);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore extra `values`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(['a'], [1, 2]), { 'a': 1 });
+    });
+
+    QUnit.test('`_.' + methodName + '` should assign `undefined` values for extra `keys`', function(assert) {
+      assert.expect(1);
+
+      assert.deepEqual(func(['a', 'b'], [1]), { 'a': 1, 'b': undefined });
+    });
+
+    QUnit.test('`_.' + methodName + '` should ' + (isDeep ? '' : 'not ') + 'support deep paths', function(assert) {
+      assert.expect(2);
+
+      lodashStable.each(['a.b.c', ['a', 'b', 'c']], function(path, index) {
+        var expected = isDeep ? ({ 'a': { 'b': { 'c': 1 } } }) : (index ? { 'a,b,c': 1 } : { 'a.b.c': 1 });
+        assert.deepEqual(func([path], [1]), expected);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should work in a lazy sequence', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var values = lodashStable.range(LARGE_ARRAY_SIZE),
+            props = lodashStable.map(values, function(value) { return 'key' + value; }),
+            actual = _(props)[methodName](values).map(square).filter(isEven).take().value();
+
+        assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven)));
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.zipWith');
+
+  (function() {
+    QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) {
+      assert.expect(2);
+
+      var array1 = [1, 2, 3],
+          array2 = [4, 5, 6],
+          array3 = [7, 8, 9];
+
+      var actual = _.zipWith(array1, array2, array3, function(a, b, c) {
+        return a + b + c;
+      });
+
+      assert.deepEqual(actual, [12, 15, 18]);
+
+      var actual = _.zipWith(array1, [], function(a, b) {
+        return a + (b || 0);
+      });
+
+      assert.deepEqual(actual, [1, 2, 3]);
+    });
+
+    QUnit.test('should provide the correct `iteratee` arguments', function(assert) {
+      assert.expect(1);
+
+      var args;
+
+      _.zipWith([1, 2], [3, 4], [5, 6], function() {
+        args || (args = slice.call(arguments));
+      });
+
+      assert.deepEqual(args, [1, 3, 5]);
+    });
+
+    QUnit.test('should perform a basic zip when `iteratee` is nullish', function(assert) {
+      assert.expect(1);
+
+      var array1 = [1, 2],
+          array2 = [3, 4],
+          values = [, null, undefined],
+          expected = lodashStable.map(values, lodashStable.constant(_.zip(array1, array2)));
+
+      var actual = lodashStable.map(values, function(value, index) {
+        return index ? _.zipWith(array1, array2, value) : _.zipWith(array1, array2);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash.unzip and lodash.zip');
+
+  lodashStable.each(['unzip', 'zip'], function(methodName, index) {
+    var func = _[methodName];
+    func = lodashStable.bind(index ? func.apply : func.call, func, null);
+
+    var object = {
+      'an empty array': [
+        [],
+        []
+      ],
+      '0-tuples': [
+        [[], []],
+        []
+      ],
+      '2-tuples': [
+        [['barney', 'fred'], [36, 40]],
+        [['barney', 36], ['fred', 40]]
+      ],
+      '3-tuples': [
+        [['barney', 'fred'], [36, 40], [false, true]],
+        [['barney', 36, false], ['fred', 40, true]]
+      ]
+    };
+
+    lodashStable.forOwn(object, function(pair, key) {
+      QUnit.test('`_.' + methodName + '` should work with ' + key, function(assert) {
+        assert.expect(2);
+
+        var actual = func(pair[0]);
+        assert.deepEqual(actual, pair[1]);
+        assert.deepEqual(func(actual), actual.length ? pair[0] : []);
+      });
+    });
+
+    QUnit.test('`_.' + methodName + '` should work with tuples of different lengths', function(assert) {
+      assert.expect(4);
+
+      var pair = [
+        [['barney', 36], ['fred', 40, false]],
+        [['barney', 'fred'], [36, 40], [undefined, false]]
+      ];
+
+      var actual = func(pair[0]);
+      assert.ok('0' in actual[2]);
+      assert.deepEqual(actual, pair[1]);
+
+      actual = func(actual);
+      assert.ok('2' in actual[0]);
+      assert.deepEqual(actual, [['barney', 36, undefined], ['fred', 40, false]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should treat falsey values as empty arrays', function(assert) {
+      assert.expect(1);
+
+      var expected = lodashStable.map(falsey, alwaysEmptyArray);
+
+      var actual = lodashStable.map(falsey, function(value) {
+        return func([value, value, value]);
+      });
+
+      assert.deepEqual(actual, expected);
+    });
+
+    QUnit.test('`_.' + methodName + '` should ignore values that are not arrays or `arguments` objects', function(assert) {
+      assert.expect(1);
+
+      var array = [[1, 2], [3, 4], null, undefined, { '0': 1 }];
+      assert.deepEqual(func(array), [[1, 3], [2, 4]]);
+    });
+
+    QUnit.test('`_.' + methodName + '` should support consuming its return value', function(assert) {
+      assert.expect(1);
+
+      var expected = [['barney', 'fred'], [36, 40]];
+      assert.deepEqual(func(func(func(func(expected)))), expected);
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).commit');
+
+  (function() {
+    QUnit.test('should execute the chained sequence and returns the wrapped result', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var array = [1],
+            wrapped = _(array).push(2).push(3);
+
+        assert.deepEqual(array, [1]);
+
+        var otherWrapper = wrapped.commit();
+        assert.ok(otherWrapper instanceof _);
+        assert.deepEqual(otherWrapper.value(), [1, 2, 3]);
+        assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should track the `__chain__` value of a wrapper', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var wrapped = _([1]).chain().commit().head();
+        assert.ok(wrapped instanceof _);
+        assert.strictEqual(wrapped.value(), 1);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).next');
+
+  lodashStable.each([false, true], function(implict) {
+    function chain(value) {
+      return implict ? _(value) : _.chain(value);
+    }
+
+    var chainType = 'in an ' + (implict ? 'implict' : 'explict') + ' chain';
+
+    QUnit.test('should follow the iterator protocol ' + chainType, function(assert) {
+      assert.expect(3);
+
+      if (!isNpm) {
+        var wrapped = chain([1, 2]);
+
+        assert.deepEqual(wrapped.next(), { 'done': false, 'value': 1 });
+        assert.deepEqual(wrapped.next(), { 'done': false, 'value': 2 });
+        assert.deepEqual(wrapped.next(), { 'done': true,  'value': undefined });
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should act as an iterable ' + chainType, function(assert) {
+      assert.expect(2);
+
+      if (!isNpm && Symbol && Symbol.iterator) {
+        var array = [1, 2],
+            wrapped = chain(array);
+
+        assert.strictEqual(wrapped[Symbol.iterator](), wrapped);
+        assert.deepEqual(_.toArray(wrapped), array);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should use `_.toArray` to generate the iterable result ' + chainType, function(assert) {
+      assert.expect(3);
+
+      if (!isNpm && Array.from) {
+        var hearts = '\ud83d\udc95',
+            values = [[1], { 'a': 1 }, hearts];
+
+        lodashStable.each(values, function(value) {
+          var wrapped = chain(value);
+          assert.deepEqual(Array.from(wrapped), _.toArray(value));
+        });
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+
+    QUnit.test('should reset the iterator correctly ' + chainType, function(assert) {
+      assert.expect(4);
+
+      if (!isNpm && Symbol && Symbol.iterator) {
+        var array = [1, 2],
+            wrapped = chain(array);
+
+        assert.deepEqual(_.toArray(wrapped), array);
+        assert.deepEqual(_.toArray(wrapped), [], 'produces an empty array for exhausted iterator');
+
+        var other = wrapped.filter();
+        assert.deepEqual(_.toArray(other), array, 'reset for new chain segments');
+        assert.deepEqual(_.toArray(wrapped), [], 'iterator is still exhausted');
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should work in a lazy sequence ' + chainType, function(assert) {
+      assert.expect(3);
+
+      if (!isNpm && Symbol && Symbol.iterator) {
+        var array = lodashStable.range(LARGE_ARRAY_SIZE),
+            predicate = function(value) { values.push(value); return isEven(value); },
+            values = [],
+            wrapped = chain(array);
+
+        assert.deepEqual(_.toArray(wrapped), array);
+
+        wrapped = wrapped.filter(predicate);
+        assert.deepEqual(_.toArray(wrapped), _.filter(array, isEven), 'reset for new lazy chain segments');
+        assert.deepEqual(values, array, 'memoizes iterator values');
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+  });
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).plant');
+
+  (function() {
+    QUnit.test('should clone the chained sequence planting `value` as the wrapped value', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array1 = [5, null, 3, null, 1],
+            array2 = [10, null, 8, null, 6],
+            wrapped1 = _(array1).thru(_.compact).map(square).takeRight(2).sort(),
+            wrapped2 = wrapped1.plant(array2);
+
+        assert.deepEqual(wrapped2.value(), [36, 64]);
+        assert.deepEqual(wrapped1.value(), [1, 9]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should clone `chainAll` settings', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var array1 = [2, 4],
+            array2 = [6, 8],
+            wrapped1 = _(array1).chain().map(square),
+            wrapped2 = wrapped1.plant(array2);
+
+        assert.deepEqual(wrapped2.head().value(), 36);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should reset iterator data on cloned sequences', function(assert) {
+      assert.expect(3);
+
+      if (!isNpm && Symbol && Symbol.iterator) {
+        var array1 = [2, 4],
+            array2 = [6, 8],
+            wrapped1 = _(array1).map(square);
+
+        assert.deepEqual(_.toArray(wrapped1), [4, 16]);
+        assert.deepEqual(_.toArray(wrapped1), []);
+
+        var wrapped2 = wrapped1.plant(array2);
+        assert.deepEqual(_.toArray(wrapped2), [36, 64]);
+      }
+      else {
+        skipAssert(assert, 3);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).pop');
+
+  (function() {
+    QUnit.test('should remove elements from the end of `array`', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var array = [1, 2],
+            wrapped = _(array);
+
+        assert.strictEqual(wrapped.pop(), 2);
+        assert.deepEqual(wrapped.value(), [1]);
+        assert.strictEqual(wrapped.pop(), 1);
+
+        var actual = wrapped.value();
+        assert.deepEqual(actual, []);
+        assert.strictEqual(actual, array);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            var result = index ? _(value).pop() : _().pop();
+            return result === undefined;
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).push');
+
+  (function() {
+    QUnit.test('should append elements to `array`', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array = [1],
+            wrapped = _(array).push(2, 3),
+            actual = wrapped.value();
+
+        assert.strictEqual(actual, array);
+        assert.deepEqual(actual, [1, 2, 3]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            var result = index ? _(value).push(1).value() : _().push(1).value();
+            return lodashStable.eq(result, value);
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).shift');
+
+  (function() {
+    QUnit.test('should remove elements from the front of `array`', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var array = [1, 2],
+            wrapped = _(array);
+
+        assert.strictEqual(wrapped.shift(), 1);
+        assert.deepEqual(wrapped.value(), [2]);
+        assert.strictEqual(wrapped.shift(), 2);
+
+        var actual = wrapped.value();
+        assert.deepEqual(actual, []);
+        assert.strictEqual(actual, array);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            var result = index ? _(value).shift() : _().shift();
+            return result === undefined;
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).sort');
+
+  (function() {
+    QUnit.test('should return the wrapped sorted `array`', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array = [3, 1, 2],
+            wrapped = _(array).sort(),
+            actual = wrapped.value();
+
+        assert.strictEqual(actual, array);
+        assert.deepEqual(actual, [1, 2, 3]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            var result = index ? _(value).sort().value() : _().sort().value();
+            return lodashStable.eq(result, value);
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).splice');
+
+  (function() {
+    QUnit.test('should support removing and inserting elements', function(assert) {
+      assert.expect(5);
+
+      if (!isNpm) {
+        var array = [1, 2],
+            wrapped = _(array);
+
+        assert.deepEqual(wrapped.splice(1, 1, 3).value(), [2]);
+        assert.deepEqual(wrapped.value(), [1, 3]);
+        assert.deepEqual(wrapped.splice(0, 2).value(), [1, 3]);
+
+        var actual = wrapped.value();
+        assert.deepEqual(actual, []);
+        assert.strictEqual(actual, array);
+      }
+      else {
+        skipAssert(assert, 5);
+      }
+    });
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            var result = index ? _(value).splice(0, 1).value() : _().splice(0, 1).value();
+            return lodashStable.isEqual(result, []);
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).unshift');
+
+  (function() {
+    QUnit.test('should prepend elements to `array`', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var array = [3],
+            wrapped = _(array).unshift(1, 2),
+            actual = wrapped.value();
+
+        assert.strictEqual(actual, array);
+        assert.deepEqual(actual, [1, 2, 3]);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var expected = lodashStable.map(falsey, alwaysTrue);
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            var result = index ? _(value).unshift(1).value() : _().unshift(1).value();
+            return lodashStable.eq(result, value);
+          } catch (e) {}
+        });
+
+        assert.deepEqual(actual, expected);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...).value');
+
+  (function() {
+    QUnit.test('should execute the chained sequence and extract the unwrapped value', function(assert) {
+      assert.expect(4);
+
+      if (!isNpm) {
+        var array = [1],
+            wrapped = _(array).push(2).push(3);
+
+        assert.deepEqual(array, [1]);
+        assert.deepEqual(wrapped.value(), [1, 2, 3]);
+        assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]);
+        assert.deepEqual(array, [1, 2, 3, 2, 3]);
+      }
+      else {
+        skipAssert(assert, 4);
+      }
+    });
+
+    QUnit.test('should return the `valueOf` result of the wrapped value', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm) {
+        var wrapped = _(123);
+        assert.strictEqual(Number(wrapped), 123);
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should stringify the wrapped value when used by `JSON.stringify`', function(assert) {
+      assert.expect(1);
+
+      if (!isNpm && JSON) {
+        var wrapped = _([1, 2, 3]);
+        assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]');
+      }
+      else {
+        skipAssert(assert);
+      }
+    });
+
+    QUnit.test('should be aliased', function(assert) {
+      assert.expect(2);
+
+      if (!isNpm) {
+        var expected = _.prototype.value;
+        assert.strictEqual(_.prototype.toJSON, expected);
+        assert.strictEqual(_.prototype.valueOf, expected);
+      }
+      else {
+        skipAssert(assert, 2);
+      }
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...) methods that return the wrapped modified array');
+
+  (function() {
+    var funcs = [
+      'push',
+      'reverse',
+      'sort',
+      'unshift'
+    ];
+
+    lodashStable.each(funcs, function(methodName) {
+      QUnit.test('`_(...).' + methodName + '` should return a new wrapper', function(assert) {
+        assert.expect(2);
+
+        if (!isNpm) {
+          var array = [1, 2, 3],
+              wrapped = _(array),
+              actual = wrapped[methodName]();
+
+          assert.ok(actual instanceof _);
+          assert.notStrictEqual(actual, wrapped);
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...) methods that return new wrapped values');
+
+  (function() {
+    var funcs = [
+      'castArray',
+      'concat',
+      'difference',
+      'differenceBy',
+      'differenceWith',
+      'intersection',
+      'intersectionBy',
+      'intersectionWith',
+      'pull',
+      'pullAll',
+      'pullAt',
+      'sampleSize',
+      'shuffle',
+      'slice',
+      'splice',
+      'split',
+      'toArray',
+      'union',
+      'unionBy',
+      'unionWith',
+      'uniq',
+      'uniqBy',
+      'uniqWith',
+      'words',
+      'xor',
+      'xorBy',
+      'xorWith'
+    ];
+
+    lodashStable.each(funcs, function(methodName) {
+      QUnit.test('`_(...).' + methodName + '` should return a new wrapped value', function(assert) {
+        assert.expect(2);
+
+        if (!isNpm) {
+          var value = methodName == 'split' ? 'abc' : [1, 2, 3],
+              wrapped = _(value),
+              actual = wrapped[methodName]();
+
+          assert.ok(actual instanceof _);
+          assert.notStrictEqual(actual, wrapped);
+        }
+        else {
+          skipAssert(assert, 2);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash(...) methods that return unwrapped values');
+
+  (function() {
+    var funcs = [
+      'add',
+      'camelCase',
+      'capitalize',
+      'ceil',
+      'clone',
+      'deburr',
+      'divide',
+      'endsWith',
+      'escape',
+      'escapeRegExp',
+      'every',
+      'find',
+      'floor',
+      'has',
+      'hasIn',
+      'head',
+      'includes',
+      'isArguments',
+      'isArray',
+      'isArrayBuffer',
+      'isArrayLike',
+      'isBoolean',
+      'isBuffer',
+      'isDate',
+      'isElement',
+      'isEmpty',
+      'isEqual',
+      'isError',
+      'isFinite',
+      'isFunction',
+      'isInteger',
+      'isMap',
+      'isNaN',
+      'isNative',
+      'isNil',
+      'isNull',
+      'isNumber',
+      'isObject',
+      'isObjectLike',
+      'isPlainObject',
+      'isRegExp',
+      'isSafeInteger',
+      'isSet',
+      'isString',
+      'isUndefined',
+      'isWeakMap',
+      'isWeakSet',
+      'join',
+      'kebabCase',
+      'last',
+      'lowerCase',
+      'lowerFirst',
+      'max',
+      'maxBy',
+      'min',
+      'minBy',
+      'multiply',
+      'nth',
+      'pad',
+      'padEnd',
+      'padStart',
+      'parseInt',
+      'pop',
+      'random',
+      'reduce',
+      'reduceRight',
+      'repeat',
+      'replace',
+      'round',
+      'sample',
+      'shift',
+      'size',
+      'snakeCase',
+      'some',
+      'startCase',
+      'startsWith',
+      'subtract',
+      'sum',
+      'toInteger',
+      'toLower',
+      'toNumber',
+      'toSafeInteger',
+      'toString',
+      'toUpper',
+      'trim',
+      'trimEnd',
+      'trimStart',
+      'truncate',
+      'unescape',
+      'upperCase',
+      'upperFirst'
+    ];
+
+    lodashStable.each(funcs, function(methodName) {
+      QUnit.test('`_(...).' + methodName + '` should return an unwrapped value when implicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          var actual = _()[methodName]();
+          assert.notOk(actual instanceof _);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+
+      QUnit.test('`_(...).' + methodName + '` should return a wrapped value when explicitly chaining', function(assert) {
+        assert.expect(1);
+
+        if (!isNpm) {
+          var actual = _().chain()[methodName]();
+          assert.ok(actual instanceof _);
+        }
+        else {
+          skipAssert(assert);
+        }
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('"Arrays" category methods');
+
+  (function() {
+    var args = (function() { return arguments; }(1, null, [3], null, 5)),
+        sortedArgs = (function() { return arguments; }(1, [3], 5, null, null)),
+        array = [1, 2, 3, 4, 5, 6];
+
+    QUnit.test('should work with `arguments` objects', function(assert) {
+      assert.expect(30);
+
+      function message(methodName) {
+        return '`_.' + methodName + '` should work with `arguments` objects';
+      }
+
+      assert.deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
+      assert.deepEqual(_.difference(array, args), [2, 3, 4, 6], '_.difference should work with `arguments` objects as secondary arguments');
+
+      assert.deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
+      assert.deepEqual(_.union(array, args), array.concat([null, [3]]), '_.union should work with `arguments` objects as secondary arguments');
+
+      assert.deepEqual(_.compact(args), [1, [3], 5], message('compact'));
+      assert.deepEqual(_.drop(args, 3), [null, 5], message('drop'));
+      assert.deepEqual(_.dropRight(args, 3), [1, null], message('dropRight'));
+      assert.deepEqual(_.dropRightWhile(args,identity), [1, null, [3], null], message('dropRightWhile'));
+      assert.deepEqual(_.dropWhile(args,identity), [null, [3], null, 5], message('dropWhile'));
+      assert.deepEqual(_.findIndex(args, identity), 0, message('findIndex'));
+      assert.deepEqual(_.findLastIndex(args, identity), 4, message('findLastIndex'));
+      assert.deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
+      assert.deepEqual(_.head(args), 1, message('head'));
+      assert.deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
+      assert.deepEqual(_.initial(args), [1, null, [3], null], message('initial'));
+      assert.deepEqual(_.intersection(args, [1]), [1], message('intersection'));
+      assert.deepEqual(_.last(args), 5, message('last'));
+      assert.deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
+      assert.deepEqual(_.sortedIndex(sortedArgs, 6), 3, message('sortedIndex'));
+      assert.deepEqual(_.sortedIndexOf(sortedArgs, 5), 2, message('sortedIndexOf'));
+      assert.deepEqual(_.sortedLastIndex(sortedArgs, 5), 3, message('sortedLastIndex'));
+      assert.deepEqual(_.sortedLastIndexOf(sortedArgs, 1), 0, message('sortedLastIndexOf'));
+      assert.deepEqual(_.tail(args, 4), [null, [3], null, 5], message('tail'));
+      assert.deepEqual(_.take(args, 2), [1, null], message('take'));
+      assert.deepEqual(_.takeRight(args, 1), [5], message('takeRight'));
+      assert.deepEqual(_.takeRightWhile(args, identity), [5], message('takeRightWhile'));
+      assert.deepEqual(_.takeWhile(args, identity), [1], message('takeWhile'));
+      assert.deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
+      assert.deepEqual(_.without(args, null), [1, [3], 5], message('without'));
+      assert.deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
+    });
+
+    QUnit.test('should accept falsey primary arguments', function(assert) {
+      assert.expect(4);
+
+      function message(methodName) {
+        return '`_.' + methodName + '` should accept falsey primary arguments';
+      }
+
+      assert.deepEqual(_.difference(null, array), [], message('difference'));
+      assert.deepEqual(_.intersection(null, array), [], message('intersection'));
+      assert.deepEqual(_.union(null, array), array, message('union'));
+      assert.deepEqual(_.xor(null, array), array, message('xor'));
+    });
+
+    QUnit.test('should accept falsey secondary arguments', function(assert) {
+      assert.expect(3);
+
+      function message(methodName) {
+        return '`_.' + methodName + '` should accept falsey secondary arguments';
+      }
+
+      assert.deepEqual(_.difference(array, null), array, message('difference'));
+      assert.deepEqual(_.intersection(array, null), [], message('intersection'));
+      assert.deepEqual(_.union(array, null), array, message('union'));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('"Strings" category methods');
+
+  (function() {
+    var stringMethods = [
+      'camelCase',
+      'capitalize',
+      'escape',
+      'kebabCase',
+      'lowerCase',
+      'lowerFirst',
+      'pad',
+      'padEnd',
+      'padStart',
+      'repeat',
+      'snakeCase',
+      'toLower',
+      'toUpper',
+      'trim',
+      'trimEnd',
+      'trimStart',
+      'truncate',
+      'unescape',
+      'upperCase',
+      'upperFirst'
+    ];
+
+    lodashStable.each(stringMethods, function(methodName) {
+      var func = _[methodName];
+
+      QUnit.test('`_.' + methodName + '` should return an empty string for empty values', function(assert) {
+        assert.expect(1);
+
+        var values = [, null, undefined, ''],
+            expected = lodashStable.map(values, alwaysEmptyString);
+
+        var actual = lodashStable.map(values, function(value, index) {
+          return index ? func(value) : func();
+        });
+
+        assert.deepEqual(actual, expected);
+      });
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.module('lodash methods');
+
+  (function() {
+    var allMethods = lodashStable.reject(_.functions(_).sort(), function(methodName) {
+      return lodashStable.startsWith(methodName, '_');
+    });
+
+    var checkFuncs = [
+      'after',
+      'ary',
+      'before',
+      'bind',
+      'curry',
+      'curryRight',
+      'debounce',
+      'defer',
+      'delay',
+      'flip',
+      'flow',
+      'flowRight',
+      'memoize',
+      'negate',
+      'once',
+      'partial',
+      'partialRight',
+      'rearg',
+      'rest',
+      'spread',
+      'throttle',
+      'unary'
+    ];
+
+    var noBinding = [
+      'flip',
+      'memoize',
+      'negate',
+      'once',
+      'overArgs',
+      'partial',
+      'partialRight',
+      'rearg',
+      'rest',
+      'spread'
+    ];
+
+    var rejectFalsey = [
+      'tap',
+      'thru'
+    ].concat(checkFuncs);
+
+    var returnArrays = [
+      'at',
+      'chunk',
+      'compact',
+      'difference',
+      'drop',
+      'filter',
+      'flatten',
+      'functions',
+      'initial',
+      'intersection',
+      'invokeMap',
+      'keys',
+      'map',
+      'orderBy',
+      'pull',
+      'pullAll',
+      'pullAt',
+      'range',
+      'rangeRight',
+      'reject',
+      'remove',
+      'shuffle',
+      'sortBy',
+      'tail',
+      'take',
+      'times',
+      'toArray',
+      'toPairs',
+      'toPairsIn',
+      'union',
+      'uniq',
+      'values',
+      'without',
+      'xor',
+      'zip'
+    ];
+
+    var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey);
+
+    QUnit.test('should accept falsey arguments', function(assert) {
+      assert.expect(308);
+
+      var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);
+
+      lodashStable.each(acceptFalsey, function(methodName) {
+        var expected = emptyArrays,
+            func = _[methodName],
+            pass = true;
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          try {
+            return index ? func(value) : func();
+          } catch (e) {
+            pass = false;
+          }
+        });
+
+        if (methodName == 'noConflict') {
+          root._ = oldDash;
+        }
+        else if (methodName == 'pull' || methodName == 'pullAll') {
+          expected = falsey;
+        }
+        if (lodashStable.includes(returnArrays, methodName) && methodName != 'sample') {
+          assert.deepEqual(actual, expected, '_.' + methodName + ' returns an array');
+        }
+        assert.ok(pass, '`_.' + methodName + '` accepts falsey arguments');
+      });
+
+      // Skip tests for missing methods of modularized builds.
+      lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) {
+        if (!_[methodName]) {
+          skipAssert(assert);
+        }
+      });
+    });
+
+    QUnit.test('should return an array', function(assert) {
+      assert.expect(70);
+
+      var array = [1, 2, 3];
+
+      lodashStable.each(returnArrays, function(methodName) {
+        var actual,
+            func = _[methodName];
+
+        switch (methodName) {
+          case 'invokeMap':
+            actual = func(array, 'toFixed');
+            break;
+          case 'sample':
+            actual = func(array, 1);
+            break;
+          default:
+            actual = func(array);
+        }
+        assert.ok(lodashStable.isArray(actual), '_.' + methodName + ' returns an array');
+
+        var isPull = methodName == 'pull' || methodName == 'pullAll';
+        assert.strictEqual(actual === array, isPull, '_.' + methodName + ' should ' + (isPull ? '' : 'not ') + 'return the given array');
+      });
+    });
+
+    QUnit.test('should throw an error for falsey arguments', function(assert) {
+      assert.expect(24);
+
+      lodashStable.each(rejectFalsey, function(methodName) {
+        var expected = lodashStable.map(falsey, alwaysTrue),
+            func = _[methodName];
+
+        var actual = lodashStable.map(falsey, function(value, index) {
+          var pass = !index && /^(?:backflow|compose|cond|flow(Right)?|over(?:Every|Some)?)$/.test(methodName);
+
+          try {
+            index ? func(value) : func();
+          } catch (e) {
+            pass = !pass && (e instanceof TypeError) &&
+              (!lodashStable.includes(checkFuncs, methodName) || (e.message == FUNC_ERROR_TEXT));
+          }
+          return pass;
+        });
+
+        assert.deepEqual(actual, expected, '`_.' + methodName + '` rejects falsey arguments');
+      });
+    });
+
+    QUnit.test('should not set a `this` binding', function(assert) {
+      assert.expect(30);
+
+      lodashStable.each(noBinding, function(methodName) {
+        var fn = function() { return this.a; },
+            func = _[methodName],
+            isNegate = methodName == 'negate',
+            object = { 'a': 1 },
+            expected = isNegate ? false : 1;
+
+        var wrapper = func(_.bind(fn, object));
+        assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can consume a bound function');
+
+        wrapper = _.bind(func(fn), object);
+        assert.strictEqual(wrapper(), expected, '`_.' + methodName + '` can be bound');
+
+        object.wrapper = func(fn);
+        assert.strictEqual(object.wrapper(), expected, '`_.' + methodName + '` uses the `this` of its parent object');
+      });
+    });
+
+    QUnit.test('should not contain minified method names (test production builds)', function(assert) {
+      assert.expect(1);
+
+      var shortNames = ['_', 'at', 'eq', 'gt', 'lt'];
+      assert.ok(lodashStable.every(_.functions(_), function(methodName) {
+        return methodName.length > 2 || lodashStable.includes(shortNames, methodName);
+      }));
+    });
+  }());
+
+  /*--------------------------------------------------------------------------*/
+
+  QUnit.config.asyncRetries = 10;
+  QUnit.config.hidepassed = true;
+
+  if (!document) {
+    QUnit.config.noglobals = true;
+    QUnit.load();
+  }
+}.call(this));
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/test/underscore.html b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/underscore.html
new file mode 100644
index 0000000..a3e56e8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/test/underscore.html
@@ -0,0 +1,484 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>Underscore Test Suite</title>
+    <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
+  </head>
+  <body>
+    <div id="qunit"></div>
+    <script>
+      // Avoid reporting tests to Sauce Labs when script errors occur.
+      if (location.port == '9001') {
+        window.onerror = function(message) {
+          if (window.QUnit) {
+            QUnit.config.done.length = 0;
+          }
+          global_test_results = { 'message': message };
+        };
+      }
+    </script>
+    <script src="../node_modules/qunitjs/qunit/qunit.js"></script>
+    <script src="../node_modules/qunit-extras/qunit-extras.js"></script>
+    <script src="../node_modules/jquery/dist/jquery.js"></script>
+    <script src="../node_modules/platform/platform.js"></script>
+    <script src="./asset/test-ui.js"></script>
+    <script src="../lodash.js"></script>
+    <script>
+      QUnit.config.asyncRetries = 10;
+      QUnit.config.hidepassed = true;
+      QUnit.config.excused = {
+        'Arrays': {
+          'chunk': [
+            'defaults to empty array (chunk size 0)'
+          ],
+          'difference': [
+            'can perform an OO-style difference'
+          ],
+          'drop': [
+            'is an alias for rest'
+          ],
+          'first': [
+            'returns an empty array when n <= 0 (0 case)',
+            'returns an empty array when n <= 0 (negative case)',
+            'can fetch the first n elements',
+            'returns the whole array if n > length'
+          ],
+          'findIndex': [
+            'called with context'
+          ],
+          'findLastIndex': [
+            'called with context'
+          ],
+          'flatten': [
+            'supports empty arrays',
+            'can flatten nested arrays',
+            'works on an arguments object',
+            'can handle very deep arrays'
+          ],
+          'head': [
+            'is an alias for first'
+          ],
+          'indexOf': [
+            "sorted indexOf doesn't uses binary search",
+            '0'
+          ],
+          'initial': [
+            'returns all but the last n elements',
+            'returns an empty array when n > length',
+            'works on an arguments object'
+          ],
+          'intersection': [
+            'can perform an OO-style intersection'
+          ],
+          'last': [
+            'returns an empty array when n <= 0 (0 case)',
+            'returns an empty array when n <= 0 (negative case)',
+            'can fetch the last n elements',
+            'returns the whole array if n > length'
+          ],
+          'lastIndexOf': [
+            'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`',
+            'should treat non-number `fromIndex` values as `array.length`',
+            '[0,-1,-1]'
+          ],
+          'object': [
+            'an array of pairs zipped together into an object',
+            'an object converted to pairs and back to an object'
+          ],
+          'range': [
+            'range with two arguments a &amp; b, b&lt;a generates an empty array'
+          ],
+          'rest': [
+            'returns the whole array when index is 0',
+            'returns elements starting at the given index',
+            'works on an arguments object'
+          ],
+          'sortedIndex': [
+            '2',
+            '3'
+          ],
+          'tail': [
+            'is an alias for rest'
+          ],
+          'take': [
+            'is an alias for first'
+          ],
+          'uniq': [
+            'uses the result of `iterator` for uniqueness comparisons (unsorted case)',
+            '`sorted` argument defaults to false when omitted',
+            'when `iterator` is a string, uses that key for comparisons (unsorted case)',
+            'uses the result of `iterator` for uniqueness comparisons (sorted case)',
+            'when `iterator` is a string, uses that key for comparisons (sorted case)',
+            'can use falsey pluck like iterator'
+          ],
+          'union': [
+            'can perform an OO-style union'
+          ]
+        },
+        'Chaining': {
+          'pop': true,
+          'shift': true,
+          'splice': true,
+          'reverse/concat/unshift/pop/map': [
+            'can chain together array functions.'
+          ]
+        },
+        'Collections': {
+          'lookupIterator with contexts': true,
+          'Iterating objects with sketchy length properties': true,
+          'Resistant to collection length and properties changing while iterating': true,
+          'countBy': [
+            'true'
+          ],
+          'each': [
+            'context object property accessed'
+          ],
+          'every': [
+            'Can be called with object',
+            'Died on test #15',
+            'context works'
+          ],
+          'filter': [
+            'given context',
+            '[{"a":1,"b":2},{"a":1,"b":3},{"a":1,"b":4}]',
+            '[{"a":1,"b":2},{"a":2,"b":2}]',
+            'Empty object accepts all items',
+            'OO-filter'
+          ],
+          'find': [
+            '{"a":1,"b":4}',
+            'undefined when not found',
+            'undefined when searching empty list',
+            'works on objects',
+            'undefined',
+            'called with context'
+          ],
+          'findWhere': [
+            'checks properties given function'
+          ],
+          'groupBy': [
+            'true'
+          ],
+          'includes': [
+            "doesn't delegate to binary search"
+          ],
+          'invoke': [
+            'handles null & undefined'
+          ],
+          'map': [
+            'tripled numbers with context',
+            'OO-style doubled numbers'
+          ],
+          'max': [
+            'can handle null/undefined',
+            'can perform a computation-based max',
+            'Maximum value of an empty object',
+            'Maximum value of an empty array',
+            'Maximum value of a non-numeric collection',
+            'Finds correct max in array starting with num and containing a NaN',
+            'Finds correct max in array starting with NaN',
+            'Respects iterator return value of -Infinity',
+            'String keys use property iterator',
+            'Iterator context',
+            'Lookup falsy iterator'
+          ],
+          'min': [
+            'can handle null/undefined',
+            'can perform a computation-based min',
+            'Minimum value of an empty object',
+            'Minimum value of an empty array',
+            'Minimum value of a non-numeric collection',
+            'Finds correct min in array starting with NaN',
+            'Respects iterator return value of Infinity',
+            'String keys use property iterator',
+            'Iterator context',
+            'Lookup falsy iterator'
+          ],
+          'partition': [
+            'can reference the array index',
+            'Died on test #8',
+            'partition takes a context argument',
+            'function(a){[code]}'
+          ],
+          'pluck': [
+            '[1]'
+          ],
+          'reduce': [
+            'can reduce with a context object'
+          ],
+          'reject': [
+            'Returns empty list given empty array'
+          ],
+          'sample': [
+            'behaves correctly on negative n',
+            'Died on test #3'
+          ],
+          'some': [
+            'Can be called with object',
+            'Died on test #17',
+            'context works'
+          ],
+          'where': [
+            'checks properties given function'
+          ],
+          'Can use various collection methods on NodeLists': [
+            '<span id="id2"></span>',
+            '<span id="id1"></span>'
+          ]
+        },
+        'Functions': {
+          'debounce asap': true,
+          'debounce asap cancel': true,
+          'debounce after system time is set backwards': true,
+          'debounce asap recursively': true,
+          'throttle repeatedly with results': true,
+          'more throttle does not trigger leading call when leading is set to false': true,
+          'throttle does not trigger trailing call when trailing is set to false': true,
+          'before': [
+            'stores a memo to the last value',
+            'provides context'
+          ],
+          'bind': [
+            'Died on test #2'
+          ],
+          'bindAll': [
+            'throws an error for bindAll with no functions named'
+          ],
+          'memoize': [
+            '{"bar":"BAR","foo":"FOO"}',
+            'Died on test #8'
+          ],
+          'partial':[
+            'can partially apply with placeholders',
+            'accepts more arguments than the number of placeholders',
+            'accepts fewer arguments than the number of placeholders',
+            'unfilled placeholders are undefined',
+            'keeps prototype',
+            'allows the placeholder to be swapped out'
+          ]
+        },
+        'Objects': {
+          '#1929 Typed Array constructors are functions': true,
+          'allKeys': [
+            'is not fooled by sparse arrays; see issue #95',
+            'is not fooled by sparse arrays with additional properties',
+            '[]'
+          ],
+          'defaults': [
+            'defaults skips nulls',
+            'defaults skips undefined'
+          ],
+          'extend': [
+            'extending null results in null',
+            'extending undefined results in undefined'
+          ],
+          'extendOwn': [
+            'extending non-objects results in returning the non-object value',
+            'extending undefined results in undefined'
+          ],
+          'functions': [
+            'also looks up functions on the prototype'
+          ],
+          'isEqual': [
+            '`0` is not equal to `-0`',
+            'Commutative equality is implemented for `0` and `-0`',
+            '`new Number(0)` and `-0` are not equal',
+            'Commutative equality is implemented for `new Number(0)` and `-0`',
+            'false'
+          ],
+          'isFinite': [
+            'Numeric strings are numbers',
+            'Number instances can be finite'
+          ],
+          'isMatch': [
+            'doesnt falsey match constructor on undefined/null'
+          ],
+          'isSet': [
+            'Died on test #9'
+          ],
+          'findKey': [
+            'called with context'
+          ],
+          'keys': [
+            'is not fooled by sparse arrays; see issue #95',
+            '[]'
+          ],
+          'mapObject': [
+            'keep context',
+            'called with context',
+            'mapValue identity'
+          ],
+          'matcher': [
+            'null matches null',
+            'treats primitives as empty'
+          ],
+          'omit': [
+            'can accept a predicate',
+            'function is given context'
+          ],
+          'pick': [
+            'can accept a predicate and context',
+            'function is given context'
+          ]
+        },
+        'Utility': {
+          'noConflict (node vm)': true,
+          'now': [
+            'Produces the correct time in milliseconds'
+          ],
+          'times': [
+            'works as a wrapper'
+          ]
+        }
+      };
+
+      var mixinPrereqs = (function() {
+        var aliasToReal = {
+          'all': 'every',
+          'allKeys': 'keysIn',
+          'any': 'some',
+          'collect': 'map',
+          'compose': 'flowRight',
+          'contains': 'includes',
+          'detect': 'find',
+          'extendOwn': 'assign',
+          'findWhere': 'find',
+          'foldl': 'reduce',
+          'foldr': 'reduceRight',
+          'include': 'includes',
+          'indexBy': 'keyBy',
+          'inject': 'reduce',
+          'invoke': 'invokeMap',
+          'mapObject': 'mapValues',
+          'matcher': 'matches',
+          'methods': 'functions',
+          'object': 'zipObject',
+          'pairs': 'toPairs',
+          'pluck': 'map',
+          'restParam': 'restArgs',
+          'select': 'filter',
+          'unique': 'uniq',
+          'where': 'filter'
+        };
+
+        var keyMap = {
+          'rest': 'tail',
+          'restArgs': 'rest'
+        };
+
+        var lodash = _.noConflict();
+
+        return function(_) {
+          lodash.defaultsDeep(_, { 'templateSettings': lodash.templateSettings });
+          lodash.mixin(_, lodash.pick(lodash, lodash.difference(lodash.functions(lodash), lodash.functions(_))));
+
+          lodash.forOwn(keyMap, function(realName, otherName) {
+            _[otherName] = lodash[realName];
+            _.prototype[otherName] = lodash.prototype[realName];
+          });
+
+          lodash.forOwn(aliasToReal, function(realName, alias) {
+            _[alias] = _[realName];
+            _.prototype[alias] = _.prototype[realName];
+          });
+        };
+      }());
+
+      // Only excuse in Sauce Labs.
+      if (!ui.isSauceLabs) {
+        delete QUnit.config.excused.Functions['throttle does not trigger trailing call when trailing is set to false'];
+        delete QUnit.config.excused.Utility.now;
+      }
+      // Load prerequisite scripts.
+      document.write(ui.urlParams.loader == 'none'
+        ? '<script src="' + ui.buildPath + '"><\/script>'
+        : '<script data-dojo-config="async:1" src="' + ui.loaderPath + '"><\/script>'
+      );
+    </script>
+    <script>
+      if (ui.urlParams.loader == 'none') {
+        mixinPrereqs(_);
+        document.write([
+          '<script src="../vendor/underscore/test/collections.js"><\/script>',
+          '<script src="../vendor/underscore/test/arrays.js"><\/script>',
+          '<script src="../vendor/underscore/test/functions.js"><\/script>',
+          '<script src="../vendor/underscore/test/objects.js"><\/script>',
+          '<script src="../vendor/underscore/test/cross-document.js"><\/script>',
+          '<script src="../vendor/underscore/test/utility.js"><\/script>',
+          '<script src="../vendor/underscore/test/chaining.js"><\/script>'
+        ].join('\n'));
+      }
+    </script>
+    <script>
+      (function() {
+        if (window.curl) {
+          curl.config({ 'apiName': 'require' });
+        }
+        if (!window.require) {
+          return;
+        }
+        // Wrap to work around tests assuming Node `require` use.
+        require = (function(func) {
+          return function() {
+            return arguments[0] === '..' ? window._ : func.apply(null, arguments);
+          };
+        }(require));
+
+        var reBasename = /[\w.-]+$/,
+            basePath = ('//' + location.host + location.pathname.replace(reBasename, '')).replace(/\btest\/$/, ''),
+            modulePath = ui.buildPath.replace(/\.js$/, ''),
+            locationPath = modulePath.replace(reBasename, '').replace(/^\/|\/$/g, ''),
+            moduleId = /\bunderscore\b/i.test(ui.buildPath) ? 'underscore' : 'lodash',
+            moduleMain = modulePath.match(reBasename)[0],
+            uid = +new Date;
+
+        function getConfig() {
+          var result = {
+            'baseUrl': './',
+            'urlArgs': 't=' + uid++,
+            'waitSeconds': 0,
+            'paths': {},
+            'packages': [{
+              'name': 'test',
+              'location': '../vendor/underscore/test',
+              'config': {
+                // Work around no global being exported.
+                'exports': 'QUnit',
+                'loader': 'curl/loader/legacy'
+              }
+            }]
+          };
+
+          if (ui.isModularize) {
+            result.packages.push({
+              'name': moduleId,
+              'location': locationPath,
+              'main': moduleMain
+            });
+          } else {
+            result.paths[moduleId] = modulePath;
+          }
+          return result;
+        }
+
+        QUnit.config.autostart = false;
+
+        require(getConfig(), [moduleId], function(lodash) {
+          mixinPrereqs(lodash);
+          require(getConfig(), [
+            'test/collections',
+            'test/arrays',
+            'test/functions',
+            'test/objects',
+            'test/cross-document',
+            'test/utility',
+            'test/chaining'
+          ], function() {
+            QUnit.start();
+          });
+        });
+      }());
+    </script>
+  </body>
+</html>
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/LICENSE b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/LICENSE
new file mode 100644
index 0000000..02c89b2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2010-2016 Jeremy Ashkenas, DocumentCloud
+
+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.
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/backbone.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/backbone.js
new file mode 100644
index 0000000..55ccb22
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/backbone.js
@@ -0,0 +1,1920 @@
+//     Backbone.js 1.3.3
+
+//     (c) 2010-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     Backbone may be freely distributed under the MIT license.
+//     For all details and documentation:
+//     http://backbonejs.org
+
+(function(factory) {
+
+  // Establish the root object, `window` (`self`) in the browser, or `global` on the server.
+  // We use `self` instead of `window` for `WebWorker` support.
+  var root = (typeof self == 'object' && self.self === self && self) ||
+            (typeof global == 'object' && global.global === global && global);
+
+  // Set up Backbone appropriately for the environment. Start with AMD.
+  if (typeof define === 'function' && define.amd) {
+    define(['underscore', 'jquery', 'exports'], function(_, $, exports) {
+      // Export global even in AMD case in case this script is loaded with
+      // others that may still expect a global Backbone.
+      root.Backbone = factory(root, exports, _, $);
+    });
+
+  // Next for Node.js or CommonJS. jQuery may not be needed as a module.
+  } else if (typeof exports !== 'undefined') {
+    var _ = require('underscore'), $;
+    try { $ = require('jquery'); } catch (e) {}
+    factory(root, exports, _, $);
+
+  // Finally, as a browser global.
+  } else {
+    root.Backbone = factory(root, {}, root._, (root.jQuery || root.Zepto || root.ender || root.$));
+  }
+
+})(function(root, Backbone, _, $) {
+
+  // Initial Setup
+  // -------------
+
+  // Save the previous value of the `Backbone` variable, so that it can be
+  // restored later on, if `noConflict` is used.
+  var previousBackbone = root.Backbone;
+
+  // Create a local reference to a common array method we'll want to use later.
+  var slice = Array.prototype.slice;
+
+  // Current version of the library. Keep in sync with `package.json`.
+  Backbone.VERSION = '1.3.3';
+
+  // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
+  // the `$` variable.
+  Backbone.$ = $;
+
+  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
+  // to its previous owner. Returns a reference to this Backbone object.
+  Backbone.noConflict = function() {
+    root.Backbone = previousBackbone;
+    return this;
+  };
+
+  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
+  // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
+  // set a `X-Http-Method-Override` header.
+  Backbone.emulateHTTP = false;
+
+  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
+  // `application/json` requests ... this will encode the body as
+  // `application/x-www-form-urlencoded` instead and will send the model in a
+  // form param named `model`.
+  Backbone.emulateJSON = false;
+
+  // Proxy Backbone class methods to Underscore functions, wrapping the model's
+  // `attributes` object or collection's `models` array behind the scenes.
+  //
+  // collection.filter(function(model) { return model.get('age') > 10 });
+  // collection.each(this.addView);
+  //
+  // `Function#apply` can be slow so we use the method's arg count, if we know it.
+  var addMethod = function(length, method, attribute) {
+    switch (length) {
+      case 1: return function() {
+        return _[method](this[attribute]);
+      };
+      case 2: return function(value) {
+        return _[method](this[attribute], value);
+      };
+      case 3: return function(iteratee, context) {
+        return _[method](this[attribute], cb(iteratee, this), context);
+      };
+      case 4: return function(iteratee, defaultVal, context) {
+        return _[method](this[attribute], cb(iteratee, this), defaultVal, context);
+      };
+      default: return function() {
+        var args = slice.call(arguments);
+        args.unshift(this[attribute]);
+        return _[method].apply(_, args);
+      };
+    }
+  };
+  var addUnderscoreMethods = function(Class, methods, attribute) {
+    _.each(methods, function(length, method) {
+      if (_[method]) Class.prototype[method] = addMethod(length, method, attribute);
+    });
+  };
+
+  // Support `collection.sortBy('attr')` and `collection.findWhere({id: 1})`.
+  var cb = function(iteratee, instance) {
+    if (_.isFunction(iteratee)) return iteratee;
+    if (_.isObject(iteratee) && !instance._isModel(iteratee)) return modelMatcher(iteratee);
+    if (_.isString(iteratee)) return function(model) { return model.get(iteratee); };
+    return iteratee;
+  };
+  var modelMatcher = function(attrs) {
+    var matcher = _.matches(attrs);
+    return function(model) {
+      return matcher(model.attributes);
+    };
+  };
+
+  // Backbone.Events
+  // ---------------
+
+  // A module that can be mixed in to *any object* in order to provide it with
+  // a custom event channel. You may bind a callback to an event with `on` or
+  // remove with `off`; `trigger`-ing an event fires all callbacks in
+  // succession.
+  //
+  //     var object = {};
+  //     _.extend(object, Backbone.Events);
+  //     object.on('expand', function(){ alert('expanded'); });
+  //     object.trigger('expand');
+  //
+  var Events = Backbone.Events = {};
+
+  // Regular expression used to split event strings.
+  var eventSplitter = /\s+/;
+
+  // Iterates over the standard `event, callback` (as well as the fancy multiple
+  // space-separated events `"change blur", callback` and jQuery-style event
+  // maps `{event: callback}`).
+  var eventsApi = function(iteratee, events, name, callback, opts) {
+    var i = 0, names;
+    if (name && typeof name === 'object') {
+      // Handle event maps.
+      if (callback !== void 0 && 'context' in opts && opts.context === void 0) opts.context = callback;
+      for (names = _.keys(name); i < names.length ; i++) {
+        events = eventsApi(iteratee, events, names[i], name[names[i]], opts);
+      }
+    } else if (name && eventSplitter.test(name)) {
+      // Handle space-separated event names by delegating them individually.
+      for (names = name.split(eventSplitter); i < names.length; i++) {
+        events = iteratee(events, names[i], callback, opts);
+      }
+    } else {
+      // Finally, standard events.
+      events = iteratee(events, name, callback, opts);
+    }
+    return events;
+  };
+
+  // Bind an event to a `callback` function. Passing `"all"` will bind
+  // the callback to all events fired.
+  Events.on = function(name, callback, context) {
+    return internalOn(this, name, callback, context);
+  };
+
+  // Guard the `listening` argument from the public API.
+  var internalOn = function(obj, name, callback, context, listening) {
+    obj._events = eventsApi(onApi, obj._events || {}, name, callback, {
+      context: context,
+      ctx: obj,
+      listening: listening
+    });
+
+    if (listening) {
+      var listeners = obj._listeners || (obj._listeners = {});
+      listeners[listening.id] = listening;
+    }
+
+    return obj;
+  };
+
+  // Inversion-of-control versions of `on`. Tell *this* object to listen to
+  // an event in another object... keeping track of what it's listening to
+  // for easier unbinding later.
+  Events.listenTo = function(obj, name, callback) {
+    if (!obj) return this;
+    var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
+    var listeningTo = this._listeningTo || (this._listeningTo = {});
+    var listening = listeningTo[id];
+
+    // This object is not listening to any other events on `obj` yet.
+    // Setup the necessary references to track the listening callbacks.
+    if (!listening) {
+      var thisId = this._listenId || (this._listenId = _.uniqueId('l'));
+      listening = listeningTo[id] = {obj: obj, objId: id, id: thisId, listeningTo: listeningTo, count: 0};
+    }
+
+    // Bind callbacks on obj, and keep track of them on listening.
+    internalOn(obj, name, callback, this, listening);
+    return this;
+  };
+
+  // The reducing API that adds a callback to the `events` object.
+  var onApi = function(events, name, callback, options) {
+    if (callback) {
+      var handlers = events[name] || (events[name] = []);
+      var context = options.context, ctx = options.ctx, listening = options.listening;
+      if (listening) listening.count++;
+
+      handlers.push({callback: callback, context: context, ctx: context || ctx, listening: listening});
+    }
+    return events;
+  };
+
+  // Remove one or many callbacks. If `context` is null, removes all
+  // callbacks with that function. If `callback` is null, removes all
+  // callbacks for the event. If `name` is null, removes all bound
+  // callbacks for all events.
+  Events.off = function(name, callback, context) {
+    if (!this._events) return this;
+    this._events = eventsApi(offApi, this._events, name, callback, {
+      context: context,
+      listeners: this._listeners
+    });
+    return this;
+  };
+
+  // Tell this object to stop listening to either specific events ... or
+  // to every object it's currently listening to.
+  Events.stopListening = function(obj, name, callback) {
+    var listeningTo = this._listeningTo;
+    if (!listeningTo) return this;
+
+    var ids = obj ? [obj._listenId] : _.keys(listeningTo);
+
+    for (var i = 0; i < ids.length; i++) {
+      var listening = listeningTo[ids[i]];
+
+      // If listening doesn't exist, this object is not currently
+      // listening to obj. Break out early.
+      if (!listening) break;
+
+      listening.obj.off(name, callback, this);
+    }
+
+    return this;
+  };
+
+  // The reducing API that removes a callback from the `events` object.
+  var offApi = function(events, name, callback, options) {
+    if (!events) return;
+
+    var i = 0, listening;
+    var context = options.context, listeners = options.listeners;
+
+    // Delete all events listeners and "drop" events.
+    if (!name && !callback && !context) {
+      var ids = _.keys(listeners);
+      for (; i < ids.length; i++) {
+        listening = listeners[ids[i]];
+        delete listeners[listening.id];
+        delete listening.listeningTo[listening.objId];
+      }
+      return;
+    }
+
+    var names = name ? [name] : _.keys(events);
+    for (; i < names.length; i++) {
+      name = names[i];
+      var handlers = events[name];
+
+      // Bail out if there are no events stored.
+      if (!handlers) break;
+
+      // Replace events if there are any remaining.  Otherwise, clean up.
+      var remaining = [];
+      for (var j = 0; j < handlers.length; j++) {
+        var handler = handlers[j];
+        if (
+          callback && callback !== handler.callback &&
+            callback !== handler.callback._callback ||
+              context && context !== handler.context
+        ) {
+          remaining.push(handler);
+        } else {
+          listening = handler.listening;
+          if (listening && --listening.count === 0) {
+            delete listeners[listening.id];
+            delete listening.listeningTo[listening.objId];
+          }
+        }
+      }
+
+      // Update tail event if the list has any events.  Otherwise, clean up.
+      if (remaining.length) {
+        events[name] = remaining;
+      } else {
+        delete events[name];
+      }
+    }
+    return events;
+  };
+
+  // Bind an event to only be triggered a single time. After the first time
+  // the callback is invoked, its listener will be removed. If multiple events
+  // are passed in using the space-separated syntax, the handler will fire
+  // once for each event, not once for a combination of all events.
+  Events.once = function(name, callback, context) {
+    // Map the event into a `{event: once}` object.
+    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.off, this));
+    if (typeof name === 'string' && context == null) callback = void 0;
+    return this.on(events, callback, context);
+  };
+
+  // Inversion-of-control versions of `once`.
+  Events.listenToOnce = function(obj, name, callback) {
+    // Map the event into a `{event: once}` object.
+    var events = eventsApi(onceMap, {}, name, callback, _.bind(this.stopListening, this, obj));
+    return this.listenTo(obj, events);
+  };
+
+  // Reduces the event callbacks into a map of `{event: onceWrapper}`.
+  // `offer` unbinds the `onceWrapper` after it has been called.
+  var onceMap = function(map, name, callback, offer) {
+    if (callback) {
+      var once = map[name] = _.once(function() {
+        offer(name, once);
+        callback.apply(this, arguments);
+      });
+      once._callback = callback;
+    }
+    return map;
+  };
+
+  // Trigger one or many events, firing all bound callbacks. Callbacks are
+  // passed the same arguments as `trigger` is, apart from the event name
+  // (unless you're listening on `"all"`, which will cause your callback to
+  // receive the true name of the event as the first argument).
+  Events.trigger = function(name) {
+    if (!this._events) return this;
+
+    var length = Math.max(0, arguments.length - 1);
+    var args = Array(length);
+    for (var i = 0; i < length; i++) args[i] = arguments[i + 1];
+
+    eventsApi(triggerApi, this._events, name, void 0, args);
+    return this;
+  };
+
+  // Handles triggering the appropriate event callbacks.
+  var triggerApi = function(objEvents, name, callback, args) {
+    if (objEvents) {
+      var events = objEvents[name];
+      var allEvents = objEvents.all;
+      if (events && allEvents) allEvents = allEvents.slice();
+      if (events) triggerEvents(events, args);
+      if (allEvents) triggerEvents(allEvents, [name].concat(args));
+    }
+    return objEvents;
+  };
+
+  // A difficult-to-believe, but optimized internal dispatch function for
+  // triggering events. Tries to keep the usual cases speedy (most internal
+  // Backbone events have 3 arguments).
+  var triggerEvents = function(events, args) {
+    var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
+    switch (args.length) {
+      case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
+      case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
+      case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
+      case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
+      default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args); return;
+    }
+  };
+
+  // Aliases for backwards compatibility.
+  Events.bind   = Events.on;
+  Events.unbind = Events.off;
+
+  // Allow the `Backbone` object to serve as a global event bus, for folks who
+  // want global "pubsub" in a convenient place.
+  _.extend(Backbone, Events);
+
+  // Backbone.Model
+  // --------------
+
+  // Backbone **Models** are the basic data object in the framework --
+  // frequently representing a row in a table in a database on your server.
+  // A discrete chunk of data and a bunch of useful, related methods for
+  // performing computations and transformations on that data.
+
+  // Create a new model with the specified attributes. A client id (`cid`)
+  // is automatically generated and assigned for you.
+  var Model = Backbone.Model = function(attributes, options) {
+    var attrs = attributes || {};
+    options || (options = {});
+    this.cid = _.uniqueId(this.cidPrefix);
+    this.attributes = {};
+    if (options.collection) this.collection = options.collection;
+    if (options.parse) attrs = this.parse(attrs, options) || {};
+    var defaults = _.result(this, 'defaults');
+    attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
+    this.set(attrs, options);
+    this.changed = {};
+    this.initialize.apply(this, arguments);
+  };
+
+  // Attach all inheritable methods to the Model prototype.
+  _.extend(Model.prototype, Events, {
+
+    // A hash of attributes whose current and previous value differ.
+    changed: null,
+
+    // The value returned during the last failed validation.
+    validationError: null,
+
+    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
+    // CouchDB users may want to set this to `"_id"`.
+    idAttribute: 'id',
+
+    // The prefix is used to create the client id which is used to identify models locally.
+    // You may want to override this if you're experiencing name clashes with model ids.
+    cidPrefix: 'c',
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // Return a copy of the model's `attributes` object.
+    toJSON: function(options) {
+      return _.clone(this.attributes);
+    },
+
+    // Proxy `Backbone.sync` by default -- but override this if you need
+    // custom syncing semantics for *this* particular model.
+    sync: function() {
+      return Backbone.sync.apply(this, arguments);
+    },
+
+    // Get the value of an attribute.
+    get: function(attr) {
+      return this.attributes[attr];
+    },
+
+    // Get the HTML-escaped value of an attribute.
+    escape: function(attr) {
+      return _.escape(this.get(attr));
+    },
+
+    // Returns `true` if the attribute contains a value that is not null
+    // or undefined.
+    has: function(attr) {
+      return this.get(attr) != null;
+    },
+
+    // Special-cased proxy to underscore's `_.matches` method.
+    matches: function(attrs) {
+      return !!_.iteratee(attrs, this)(this.attributes);
+    },
+
+    // Set a hash of model attributes on the object, firing `"change"`. This is
+    // the core primitive operation of a model, updating the data and notifying
+    // anyone who needs to know about the change in state. The heart of the beast.
+    set: function(key, val, options) {
+      if (key == null) return this;
+
+      // Handle both `"key", value` and `{key: value}` -style arguments.
+      var attrs;
+      if (typeof key === 'object') {
+        attrs = key;
+        options = val;
+      } else {
+        (attrs = {})[key] = val;
+      }
+
+      options || (options = {});
+
+      // Run validation.
+      if (!this._validate(attrs, options)) return false;
+
+      // Extract attributes and options.
+      var unset      = options.unset;
+      var silent     = options.silent;
+      var changes    = [];
+      var changing   = this._changing;
+      this._changing = true;
+
+      if (!changing) {
+        this._previousAttributes = _.clone(this.attributes);
+        this.changed = {};
+      }
+
+      var current = this.attributes;
+      var changed = this.changed;
+      var prev    = this._previousAttributes;
+
+      // For each `set` attribute, update or delete the current value.
+      for (var attr in attrs) {
+        val = attrs[attr];
+        if (!_.isEqual(current[attr], val)) changes.push(attr);
+        if (!_.isEqual(prev[attr], val)) {
+          changed[attr] = val;
+        } else {
+          delete changed[attr];
+        }
+        unset ? delete current[attr] : current[attr] = val;
+      }
+
+      // Update the `id`.
+      if (this.idAttribute in attrs) this.id = this.get(this.idAttribute);
+
+      // Trigger all relevant attribute changes.
+      if (!silent) {
+        if (changes.length) this._pending = options;
+        for (var i = 0; i < changes.length; i++) {
+          this.trigger('change:' + changes[i], this, current[changes[i]], options);
+        }
+      }
+
+      // You might be wondering why there's a `while` loop here. Changes can
+      // be recursively nested within `"change"` events.
+      if (changing) return this;
+      if (!silent) {
+        while (this._pending) {
+          options = this._pending;
+          this._pending = false;
+          this.trigger('change', this, options);
+        }
+      }
+      this._pending = false;
+      this._changing = false;
+      return this;
+    },
+
+    // Remove an attribute from the model, firing `"change"`. `unset` is a noop
+    // if the attribute doesn't exist.
+    unset: function(attr, options) {
+      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
+    },
+
+    // Clear all attributes on the model, firing `"change"`.
+    clear: function(options) {
+      var attrs = {};
+      for (var key in this.attributes) attrs[key] = void 0;
+      return this.set(attrs, _.extend({}, options, {unset: true}));
+    },
+
+    // Determine if the model has changed since the last `"change"` event.
+    // If you specify an attribute name, determine if that attribute has changed.
+    hasChanged: function(attr) {
+      if (attr == null) return !_.isEmpty(this.changed);
+      return _.has(this.changed, attr);
+    },
+
+    // Return an object containing all the attributes that have changed, or
+    // false if there are no changed attributes. Useful for determining what
+    // parts of a view need to be updated and/or what attributes need to be
+    // persisted to the server. Unset attributes will be set to undefined.
+    // You can also pass an attributes object to diff against the model,
+    // determining if there *would be* a change.
+    changedAttributes: function(diff) {
+      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+      var old = this._changing ? this._previousAttributes : this.attributes;
+      var changed = {};
+      for (var attr in diff) {
+        var val = diff[attr];
+        if (_.isEqual(old[attr], val)) continue;
+        changed[attr] = val;
+      }
+      return _.size(changed) ? changed : false;
+    },
+
+    // Get the previous value of an attribute, recorded at the time the last
+    // `"change"` event was fired.
+    previous: function(attr) {
+      if (attr == null || !this._previousAttributes) return null;
+      return this._previousAttributes[attr];
+    },
+
+    // Get all of the attributes of the model at the time of the previous
+    // `"change"` event.
+    previousAttributes: function() {
+      return _.clone(this._previousAttributes);
+    },
+
+    // Fetch the model from the server, merging the response with the model's
+    // local attributes. Any changed attributes will trigger a "change" event.
+    fetch: function(options) {
+      options = _.extend({parse: true}, options);
+      var model = this;
+      var success = options.success;
+      options.success = function(resp) {
+        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
+        if (!model.set(serverAttrs, options)) return false;
+        if (success) success.call(options.context, model, resp, options);
+        model.trigger('sync', model, resp, options);
+      };
+      wrapError(this, options);
+      return this.sync('read', this, options);
+    },
+
+    // Set a hash of model attributes, and sync the model to the server.
+    // If the server returns an attributes hash that differs, the model's
+    // state will be `set` again.
+    save: function(key, val, options) {
+      // Handle both `"key", value` and `{key: value}` -style arguments.
+      var attrs;
+      if (key == null || typeof key === 'object') {
+        attrs = key;
+        options = val;
+      } else {
+        (attrs = {})[key] = val;
+      }
+
+      options = _.extend({validate: true, parse: true}, options);
+      var wait = options.wait;
+
+      // If we're not waiting and attributes exist, save acts as
+      // `set(attr).save(null, opts)` with validation. Otherwise, check if
+      // the model will be valid when the attributes, if any, are set.
+      if (attrs && !wait) {
+        if (!this.set(attrs, options)) return false;
+      } else if (!this._validate(attrs, options)) {
+        return false;
+      }
+
+      // After a successful server-side save, the client is (optionally)
+      // updated with the server-side state.
+      var model = this;
+      var success = options.success;
+      var attributes = this.attributes;
+      options.success = function(resp) {
+        // Ensure attributes are restored during synchronous saves.
+        model.attributes = attributes;
+        var serverAttrs = options.parse ? model.parse(resp, options) : resp;
+        if (wait) serverAttrs = _.extend({}, attrs, serverAttrs);
+        if (serverAttrs && !model.set(serverAttrs, options)) return false;
+        if (success) success.call(options.context, model, resp, options);
+        model.trigger('sync', model, resp, options);
+      };
+      wrapError(this, options);
+
+      // Set temporary attributes if `{wait: true}` to properly find new ids.
+      if (attrs && wait) this.attributes = _.extend({}, attributes, attrs);
+
+      var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
+      if (method === 'patch' && !options.attrs) options.attrs = attrs;
+      var xhr = this.sync(method, this, options);
+
+      // Restore attributes.
+      this.attributes = attributes;
+
+      return xhr;
+    },
+
+    // Destroy this model on the server if it was already persisted.
+    // Optimistically removes the model from its collection, if it has one.
+    // If `wait: true` is passed, waits for the server to respond before removal.
+    destroy: function(options) {
+      options = options ? _.clone(options) : {};
+      var model = this;
+      var success = options.success;
+      var wait = options.wait;
+
+      var destroy = function() {
+        model.stopListening();
+        model.trigger('destroy', model, model.collection, options);
+      };
+
+      options.success = function(resp) {
+        if (wait) destroy();
+        if (success) success.call(options.context, model, resp, options);
+        if (!model.isNew()) model.trigger('sync', model, resp, options);
+      };
+
+      var xhr = false;
+      if (this.isNew()) {
+        _.defer(options.success);
+      } else {
+        wrapError(this, options);
+        xhr = this.sync('delete', this, options);
+      }
+      if (!wait) destroy();
+      return xhr;
+    },
+
+    // Default URL for the model's representation on the server -- if you're
+    // using Backbone's restful methods, override this to change the endpoint
+    // that will be called.
+    url: function() {
+      var base =
+        _.result(this, 'urlRoot') ||
+        _.result(this.collection, 'url') ||
+        urlError();
+      if (this.isNew()) return base;
+      var id = this.get(this.idAttribute);
+      return base.replace(/[^\/]$/, '$&/') + encodeURIComponent(id);
+    },
+
+    // **parse** converts a response into the hash of attributes to be `set` on
+    // the model. The default implementation is just to pass the response along.
+    parse: function(resp, options) {
+      return resp;
+    },
+
+    // Create a new model with identical attributes to this one.
+    clone: function() {
+      return new this.constructor(this.attributes);
+    },
+
+    // A model is new if it has never been saved to the server, and lacks an id.
+    isNew: function() {
+      return !this.has(this.idAttribute);
+    },
+
+    // Check if the model is currently in a valid state.
+    isValid: function(options) {
+      return this._validate({}, _.extend({}, options, {validate: true}));
+    },
+
+    // Run validation against the next complete set of model attributes,
+    // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
+    _validate: function(attrs, options) {
+      if (!options.validate || !this.validate) return true;
+      attrs = _.extend({}, this.attributes, attrs);
+      var error = this.validationError = this.validate(attrs, options) || null;
+      if (!error) return true;
+      this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
+      return false;
+    }
+
+  });
+
+  // Underscore methods that we want to implement on the Model, mapped to the
+  // number of arguments they take.
+  var modelMethods = {keys: 1, values: 1, pairs: 1, invert: 1, pick: 0,
+      omit: 0, chain: 1, isEmpty: 1};
+
+  // Mix in each Underscore method as a proxy to `Model#attributes`.
+  addUnderscoreMethods(Model, modelMethods, 'attributes');
+
+  // Backbone.Collection
+  // -------------------
+
+  // If models tend to represent a single row of data, a Backbone Collection is
+  // more analogous to a table full of data ... or a small slice or page of that
+  // table, or a collection of rows that belong together for a particular reason
+  // -- all of the messages in this particular folder, all of the documents
+  // belonging to this particular author, and so on. Collections maintain
+  // indexes of their models, both in order, and for lookup by `id`.
+
+  // Create a new **Collection**, perhaps to contain a specific type of `model`.
+  // If a `comparator` is specified, the Collection will maintain
+  // its models in sort order, as they're added and removed.
+  var Collection = Backbone.Collection = function(models, options) {
+    options || (options = {});
+    if (options.model) this.model = options.model;
+    if (options.comparator !== void 0) this.comparator = options.comparator;
+    this._reset();
+    this.initialize.apply(this, arguments);
+    if (models) this.reset(models, _.extend({silent: true}, options));
+  };
+
+  // Default options for `Collection#set`.
+  var setOptions = {add: true, remove: true, merge: true};
+  var addOptions = {add: true, remove: false};
+
+  // Splices `insert` into `array` at index `at`.
+  var splice = function(array, insert, at) {
+    at = Math.min(Math.max(at, 0), array.length);
+    var tail = Array(array.length - at);
+    var length = insert.length;
+    var i;
+    for (i = 0; i < tail.length; i++) tail[i] = array[i + at];
+    for (i = 0; i < length; i++) array[i + at] = insert[i];
+    for (i = 0; i < tail.length; i++) array[i + length + at] = tail[i];
+  };
+
+  // Define the Collection's inheritable methods.
+  _.extend(Collection.prototype, Events, {
+
+    // The default model for a collection is just a **Backbone.Model**.
+    // This should be overridden in most cases.
+    model: Model,
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // The JSON representation of a Collection is an array of the
+    // models' attributes.
+    toJSON: function(options) {
+      return this.map(function(model) { return model.toJSON(options); });
+    },
+
+    // Proxy `Backbone.sync` by default.
+    sync: function() {
+      return Backbone.sync.apply(this, arguments);
+    },
+
+    // Add a model, or list of models to the set. `models` may be Backbone
+    // Models or raw JavaScript objects to be converted to Models, or any
+    // combination of the two.
+    add: function(models, options) {
+      return this.set(models, _.extend({merge: false}, options, addOptions));
+    },
+
+    // Remove a model, or a list of models from the set.
+    remove: function(models, options) {
+      options = _.extend({}, options);
+      var singular = !_.isArray(models);
+      models = singular ? [models] : models.slice();
+      var removed = this._removeModels(models, options);
+      if (!options.silent && removed.length) {
+        options.changes = {added: [], merged: [], removed: removed};
+        this.trigger('update', this, options);
+      }
+      return singular ? removed[0] : removed;
+    },
+
+    // Update a collection by `set`-ing a new list of models, adding new ones,
+    // removing models that are no longer present, and merging models that
+    // already exist in the collection, as necessary. Similar to **Model#set**,
+    // the core operation for updating the data contained by the collection.
+    set: function(models, options) {
+      if (models == null) return;
+
+      options = _.extend({}, setOptions, options);
+      if (options.parse && !this._isModel(models)) {
+        models = this.parse(models, options) || [];
+      }
+
+      var singular = !_.isArray(models);
+      models = singular ? [models] : models.slice();
+
+      var at = options.at;
+      if (at != null) at = +at;
+      if (at > this.length) at = this.length;
+      if (at < 0) at += this.length + 1;
+
+      var set = [];
+      var toAdd = [];
+      var toMerge = [];
+      var toRemove = [];
+      var modelMap = {};
+
+      var add = options.add;
+      var merge = options.merge;
+      var remove = options.remove;
+
+      var sort = false;
+      var sortable = this.comparator && at == null && options.sort !== false;
+      var sortAttr = _.isString(this.comparator) ? this.comparator : null;
+
+      // Turn bare objects into model references, and prevent invalid models
+      // from being added.
+      var model, i;
+      for (i = 0; i < models.length; i++) {
+        model = models[i];
+
+        // If a duplicate is found, prevent it from being added and
+        // optionally merge it into the existing model.
+        var existing = this.get(model);
+        if (existing) {
+          if (merge && model !== existing) {
+            var attrs = this._isModel(model) ? model.attributes : model;
+            if (options.parse) attrs = existing.parse(attrs, options);
+            existing.set(attrs, options);
+            toMerge.push(existing);
+            if (sortable && !sort) sort = existing.hasChanged(sortAttr);
+          }
+          if (!modelMap[existing.cid]) {
+            modelMap[existing.cid] = true;
+            set.push(existing);
+          }
+          models[i] = existing;
+
+        // If this is a new, valid model, push it to the `toAdd` list.
+        } else if (add) {
+          model = models[i] = this._prepareModel(model, options);
+          if (model) {
+            toAdd.push(model);
+            this._addReference(model, options);
+            modelMap[model.cid] = true;
+            set.push(model);
+          }
+        }
+      }
+
+      // Remove stale models.
+      if (remove) {
+        for (i = 0; i < this.length; i++) {
+          model = this.models[i];
+          if (!modelMap[model.cid]) toRemove.push(model);
+        }
+        if (toRemove.length) this._removeModels(toRemove, options);
+      }
+
+      // See if sorting is needed, update `length` and splice in new models.
+      var orderChanged = false;
+      var replace = !sortable && add && remove;
+      if (set.length && replace) {
+        orderChanged = this.length !== set.length || _.some(this.models, function(m, index) {
+          return m !== set[index];
+        });
+        this.models.length = 0;
+        splice(this.models, set, 0);
+        this.length = this.models.length;
+      } else if (toAdd.length) {
+        if (sortable) sort = true;
+        splice(this.models, toAdd, at == null ? this.length : at);
+        this.length = this.models.length;
+      }
+
+      // Silently sort the collection if appropriate.
+      if (sort) this.sort({silent: true});
+
+      // Unless silenced, it's time to fire all appropriate add/sort/update events.
+      if (!options.silent) {
+        for (i = 0; i < toAdd.length; i++) {
+          if (at != null) options.index = at + i;
+          model = toAdd[i];
+          model.trigger('add', model, this, options);
+        }
+        if (sort || orderChanged) this.trigger('sort', this, options);
+        if (toAdd.length || toRemove.length || toMerge.length) {
+          options.changes = {
+            added: toAdd,
+            removed: toRemove,
+            merged: toMerge
+          };
+          this.trigger('update', this, options);
+        }
+      }
+
+      // Return the added (or merged) model (or models).
+      return singular ? models[0] : models;
+    },
+
+    // When you have more items than you want to add or remove individually,
+    // you can reset the entire set with a new list of models, without firing
+    // any granular `add` or `remove` events. Fires `reset` when finished.
+    // Useful for bulk operations and optimizations.
+    reset: function(models, options) {
+      options = options ? _.clone(options) : {};
+      for (var i = 0; i < this.models.length; i++) {
+        this._removeReference(this.models[i], options);
+      }
+      options.previousModels = this.models;
+      this._reset();
+      models = this.add(models, _.extend({silent: true}, options));
+      if (!options.silent) this.trigger('reset', this, options);
+      return models;
+    },
+
+    // Add a model to the end of the collection.
+    push: function(model, options) {
+      return this.add(model, _.extend({at: this.length}, options));
+    },
+
+    // Remove a model from the end of the collection.
+    pop: function(options) {
+      var model = this.at(this.length - 1);
+      return this.remove(model, options);
+    },
+
+    // Add a model to the beginning of the collection.
+    unshift: function(model, options) {
+      return this.add(model, _.extend({at: 0}, options));
+    },
+
+    // Remove a model from the beginning of the collection.
+    shift: function(options) {
+      var model = this.at(0);
+      return this.remove(model, options);
+    },
+
+    // Slice out a sub-array of models from the collection.
+    slice: function() {
+      return slice.apply(this.models, arguments);
+    },
+
+    // Get a model from the set by id, cid, model object with id or cid
+    // properties, or an attributes object that is transformed through modelId.
+    get: function(obj) {
+      if (obj == null) return void 0;
+      return this._byId[obj] ||
+        this._byId[this.modelId(obj.attributes || obj)] ||
+        obj.cid && this._byId[obj.cid];
+    },
+
+    // Returns `true` if the model is in the collection.
+    has: function(obj) {
+      return this.get(obj) != null;
+    },
+
+    // Get the model at the given index.
+    at: function(index) {
+      if (index < 0) index += this.length;
+      return this.models[index];
+    },
+
+    // Return models with matching attributes. Useful for simple cases of
+    // `filter`.
+    where: function(attrs, first) {
+      return this[first ? 'find' : 'filter'](attrs);
+    },
+
+    // Return the first model with matching attributes. Useful for simple cases
+    // of `find`.
+    findWhere: function(attrs) {
+      return this.where(attrs, true);
+    },
+
+    // Force the collection to re-sort itself. You don't need to call this under
+    // normal circumstances, as the set will maintain sort order as each item
+    // is added.
+    sort: function(options) {
+      var comparator = this.comparator;
+      if (!comparator) throw new Error('Cannot sort a set without a comparator');
+      options || (options = {});
+
+      var length = comparator.length;
+      if (_.isFunction(comparator)) comparator = _.bind(comparator, this);
+
+      // Run sort based on type of `comparator`.
+      if (length === 1 || _.isString(comparator)) {
+        this.models = this.sortBy(comparator);
+      } else {
+        this.models.sort(comparator);
+      }
+      if (!options.silent) this.trigger('sort', this, options);
+      return this;
+    },
+
+    // Pluck an attribute from each model in the collection.
+    pluck: function(attr) {
+      return this.map(attr + '');
+    },
+
+    // Fetch the default set of models for this collection, resetting the
+    // collection when they arrive. If `reset: true` is passed, the response
+    // data will be passed through the `reset` method instead of `set`.
+    fetch: function(options) {
+      options = _.extend({parse: true}, options);
+      var success = options.success;
+      var collection = this;
+      options.success = function(resp) {
+        var method = options.reset ? 'reset' : 'set';
+        collection[method](resp, options);
+        if (success) success.call(options.context, collection, resp, options);
+        collection.trigger('sync', collection, resp, options);
+      };
+      wrapError(this, options);
+      return this.sync('read', this, options);
+    },
+
+    // Create a new instance of a model in this collection. Add the model to the
+    // collection immediately, unless `wait: true` is passed, in which case we
+    // wait for the server to agree.
+    create: function(model, options) {
+      options = options ? _.clone(options) : {};
+      var wait = options.wait;
+      model = this._prepareModel(model, options);
+      if (!model) return false;
+      if (!wait) this.add(model, options);
+      var collection = this;
+      var success = options.success;
+      options.success = function(m, resp, callbackOpts) {
+        if (wait) collection.add(m, callbackOpts);
+        if (success) success.call(callbackOpts.context, m, resp, callbackOpts);
+      };
+      model.save(null, options);
+      return model;
+    },
+
+    // **parse** converts a response into a list of models to be added to the
+    // collection. The default implementation is just to pass it through.
+    parse: function(resp, options) {
+      return resp;
+    },
+
+    // Create a new collection with an identical list of models as this one.
+    clone: function() {
+      return new this.constructor(this.models, {
+        model: this.model,
+        comparator: this.comparator
+      });
+    },
+
+    // Define how to uniquely identify models in the collection.
+    modelId: function(attrs) {
+      return attrs[this.model.prototype.idAttribute || 'id'];
+    },
+
+    // Private method to reset all internal state. Called when the collection
+    // is first initialized or reset.
+    _reset: function() {
+      this.length = 0;
+      this.models = [];
+      this._byId  = {};
+    },
+
+    // Prepare a hash of attributes (or other model) to be added to this
+    // collection.
+    _prepareModel: function(attrs, options) {
+      if (this._isModel(attrs)) {
+        if (!attrs.collection) attrs.collection = this;
+        return attrs;
+      }
+      options = options ? _.clone(options) : {};
+      options.collection = this;
+      var model = new this.model(attrs, options);
+      if (!model.validationError) return model;
+      this.trigger('invalid', this, model.validationError, options);
+      return false;
+    },
+
+    // Internal method called by both remove and set.
+    _removeModels: function(models, options) {
+      var removed = [];
+      for (var i = 0; i < models.length; i++) {
+        var model = this.get(models[i]);
+        if (!model) continue;
+
+        var index = this.indexOf(model);
+        this.models.splice(index, 1);
+        this.length--;
+
+        // Remove references before triggering 'remove' event to prevent an
+        // infinite loop. #3693
+        delete this._byId[model.cid];
+        var id = this.modelId(model.attributes);
+        if (id != null) delete this._byId[id];
+
+        if (!options.silent) {
+          options.index = index;
+          model.trigger('remove', model, this, options);
+        }
+
+        removed.push(model);
+        this._removeReference(model, options);
+      }
+      return removed;
+    },
+
+    // Method for checking whether an object should be considered a model for
+    // the purposes of adding to the collection.
+    _isModel: function(model) {
+      return model instanceof Model;
+    },
+
+    // Internal method to create a model's ties to a collection.
+    _addReference: function(model, options) {
+      this._byId[model.cid] = model;
+      var id = this.modelId(model.attributes);
+      if (id != null) this._byId[id] = model;
+      model.on('all', this._onModelEvent, this);
+    },
+
+    // Internal method to sever a model's ties to a collection.
+    _removeReference: function(model, options) {
+      delete this._byId[model.cid];
+      var id = this.modelId(model.attributes);
+      if (id != null) delete this._byId[id];
+      if (this === model.collection) delete model.collection;
+      model.off('all', this._onModelEvent, this);
+    },
+
+    // Internal method called every time a model in the set fires an event.
+    // Sets need to update their indexes when models change ids. All other
+    // events simply proxy through. "add" and "remove" events that originate
+    // in other collections are ignored.
+    _onModelEvent: function(event, model, collection, options) {
+      if (model) {
+        if ((event === 'add' || event === 'remove') && collection !== this) return;
+        if (event === 'destroy') this.remove(model, options);
+        if (event === 'change') {
+          var prevId = this.modelId(model.previousAttributes());
+          var id = this.modelId(model.attributes);
+          if (prevId !== id) {
+            if (prevId != null) delete this._byId[prevId];
+            if (id != null) this._byId[id] = model;
+          }
+        }
+      }
+      this.trigger.apply(this, arguments);
+    }
+
+  });
+
+  // Underscore methods that we want to implement on the Collection.
+  // 90% of the core usefulness of Backbone Collections is actually implemented
+  // right here:
+  var collectionMethods = {forEach: 3, each: 3, map: 3, collect: 3, reduce: 0,
+      foldl: 0, inject: 0, reduceRight: 0, foldr: 0, find: 3, detect: 3, filter: 3,
+      select: 3, reject: 3, every: 3, all: 3, some: 3, any: 3, include: 3, includes: 3,
+      contains: 3, invoke: 0, max: 3, min: 3, toArray: 1, size: 1, first: 3,
+      head: 3, take: 3, initial: 3, rest: 3, tail: 3, drop: 3, last: 3,
+      without: 0, difference: 0, indexOf: 3, shuffle: 1, lastIndexOf: 3,
+      isEmpty: 1, chain: 1, sample: 3, partition: 3, groupBy: 3, countBy: 3,
+      sortBy: 3, indexBy: 3, findIndex: 3, findLastIndex: 3};
+
+  // Mix in each Underscore method as a proxy to `Collection#models`.
+  addUnderscoreMethods(Collection, collectionMethods, 'models');
+
+  // Backbone.View
+  // -------------
+
+  // Backbone Views are almost more convention than they are actual code. A View
+  // is simply a JavaScript object that represents a logical chunk of UI in the
+  // DOM. This might be a single item, an entire list, a sidebar or panel, or
+  // even the surrounding frame which wraps your whole app. Defining a chunk of
+  // UI as a **View** allows you to define your DOM events declaratively, without
+  // having to worry about render order ... and makes it easy for the view to
+  // react to specific changes in the state of your models.
+
+  // Creating a Backbone.View creates its initial element outside of the DOM,
+  // if an existing element is not provided...
+  var View = Backbone.View = function(options) {
+    this.cid = _.uniqueId('view');
+    _.extend(this, _.pick(options, viewOptions));
+    this._ensureElement();
+    this.initialize.apply(this, arguments);
+  };
+
+  // Cached regex to split keys for `delegate`.
+  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
+
+  // List of view options to be set as properties.
+  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
+
+  // Set up all inheritable **Backbone.View** properties and methods.
+  _.extend(View.prototype, Events, {
+
+    // The default `tagName` of a View's element is `"div"`.
+    tagName: 'div',
+
+    // jQuery delegate for element lookup, scoped to DOM elements within the
+    // current view. This should be preferred to global lookups where possible.
+    $: function(selector) {
+      return this.$el.find(selector);
+    },
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // **render** is the core function that your view should override, in order
+    // to populate its element (`this.el`), with the appropriate HTML. The
+    // convention is for **render** to always return `this`.
+    render: function() {
+      return this;
+    },
+
+    // Remove this view by taking the element out of the DOM, and removing any
+    // applicable Backbone.Events listeners.
+    remove: function() {
+      this._removeElement();
+      this.stopListening();
+      return this;
+    },
+
+    // Remove this view's element from the document and all event listeners
+    // attached to it. Exposed for subclasses using an alternative DOM
+    // manipulation API.
+    _removeElement: function() {
+      this.$el.remove();
+    },
+
+    // Change the view's element (`this.el` property) and re-delegate the
+    // view's events on the new element.
+    setElement: function(element) {
+      this.undelegateEvents();
+      this._setElement(element);
+      this.delegateEvents();
+      return this;
+    },
+
+    // Creates the `this.el` and `this.$el` references for this view using the
+    // given `el`. `el` can be a CSS selector or an HTML string, a jQuery
+    // context or an element. Subclasses can override this to utilize an
+    // alternative DOM manipulation API and are only required to set the
+    // `this.el` property.
+    _setElement: function(el) {
+      this.$el = el instanceof Backbone.$ ? el : Backbone.$(el);
+      this.el = this.$el[0];
+    },
+
+    // Set callbacks, where `this.events` is a hash of
+    //
+    // *{"event selector": "callback"}*
+    //
+    //     {
+    //       'mousedown .title':  'edit',
+    //       'click .button':     'save',
+    //       'click .open':       function(e) { ... }
+    //     }
+    //
+    // pairs. Callbacks will be bound to the view, with `this` set properly.
+    // Uses event delegation for efficiency.
+    // Omitting the selector binds the event to `this.el`.
+    delegateEvents: function(events) {
+      events || (events = _.result(this, 'events'));
+      if (!events) return this;
+      this.undelegateEvents();
+      for (var key in events) {
+        var method = events[key];
+        if (!_.isFunction(method)) method = this[method];
+        if (!method) continue;
+        var match = key.match(delegateEventSplitter);
+        this.delegate(match[1], match[2], _.bind(method, this));
+      }
+      return this;
+    },
+
+    // Add a single event listener to the view's element (or a child element
+    // using `selector`). This only works for delegate-able events: not `focus`,
+    // `blur`, and not `change`, `submit`, and `reset` in Internet Explorer.
+    delegate: function(eventName, selector, listener) {
+      this.$el.on(eventName + '.delegateEvents' + this.cid, selector, listener);
+      return this;
+    },
+
+    // Clears all callbacks previously bound to the view by `delegateEvents`.
+    // You usually don't need to use this, but may wish to if you have multiple
+    // Backbone views attached to the same DOM element.
+    undelegateEvents: function() {
+      if (this.$el) this.$el.off('.delegateEvents' + this.cid);
+      return this;
+    },
+
+    // A finer-grained `undelegateEvents` for removing a single delegated event.
+    // `selector` and `listener` are both optional.
+    undelegate: function(eventName, selector, listener) {
+      this.$el.off(eventName + '.delegateEvents' + this.cid, selector, listener);
+      return this;
+    },
+
+    // Produces a DOM element to be assigned to your view. Exposed for
+    // subclasses using an alternative DOM manipulation API.
+    _createElement: function(tagName) {
+      return document.createElement(tagName);
+    },
+
+    // Ensure that the View has a DOM element to render into.
+    // If `this.el` is a string, pass it through `$()`, take the first
+    // matching element, and re-assign it to `el`. Otherwise, create
+    // an element from the `id`, `className` and `tagName` properties.
+    _ensureElement: function() {
+      if (!this.el) {
+        var attrs = _.extend({}, _.result(this, 'attributes'));
+        if (this.id) attrs.id = _.result(this, 'id');
+        if (this.className) attrs['class'] = _.result(this, 'className');
+        this.setElement(this._createElement(_.result(this, 'tagName')));
+        this._setAttributes(attrs);
+      } else {
+        this.setElement(_.result(this, 'el'));
+      }
+    },
+
+    // Set attributes from a hash on this view's element.  Exposed for
+    // subclasses using an alternative DOM manipulation API.
+    _setAttributes: function(attributes) {
+      this.$el.attr(attributes);
+    }
+
+  });
+
+  // Backbone.sync
+  // -------------
+
+  // Override this function to change the manner in which Backbone persists
+  // models to the server. You will be passed the type of request, and the
+  // model in question. By default, makes a RESTful Ajax request
+  // to the model's `url()`. Some possible customizations could be:
+  //
+  // * Use `setTimeout` to batch rapid-fire updates into a single request.
+  // * Send up the models as XML instead of JSON.
+  // * Persist models via WebSockets instead of Ajax.
+  //
+  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
+  // as `POST`, with a `_method` parameter containing the true HTTP method,
+  // as well as all requests with the body as `application/x-www-form-urlencoded`
+  // instead of `application/json` with the model in a param named `model`.
+  // Useful when interfacing with server-side languages like **PHP** that make
+  // it difficult to read the body of `PUT` requests.
+  Backbone.sync = function(method, model, options) {
+    var type = methodMap[method];
+
+    // Default options, unless specified.
+    _.defaults(options || (options = {}), {
+      emulateHTTP: Backbone.emulateHTTP,
+      emulateJSON: Backbone.emulateJSON
+    });
+
+    // Default JSON-request options.
+    var params = {type: type, dataType: 'json'};
+
+    // Ensure that we have a URL.
+    if (!options.url) {
+      params.url = _.result(model, 'url') || urlError();
+    }
+
+    // Ensure that we have the appropriate request data.
+    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
+      params.contentType = 'application/json';
+      params.data = JSON.stringify(options.attrs || model.toJSON(options));
+    }
+
+    // For older servers, emulate JSON by encoding the request into an HTML-form.
+    if (options.emulateJSON) {
+      params.contentType = 'application/x-www-form-urlencoded';
+      params.data = params.data ? {model: params.data} : {};
+    }
+
+    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
+    // And an `X-HTTP-Method-Override` header.
+    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
+      params.type = 'POST';
+      if (options.emulateJSON) params.data._method = type;
+      var beforeSend = options.beforeSend;
+      options.beforeSend = function(xhr) {
+        xhr.setRequestHeader('X-HTTP-Method-Override', type);
+        if (beforeSend) return beforeSend.apply(this, arguments);
+      };
+    }
+
+    // Don't process data on a non-GET request.
+    if (params.type !== 'GET' && !options.emulateJSON) {
+      params.processData = false;
+    }
+
+    // Pass along `textStatus` and `errorThrown` from jQuery.
+    var error = options.error;
+    options.error = function(xhr, textStatus, errorThrown) {
+      options.textStatus = textStatus;
+      options.errorThrown = errorThrown;
+      if (error) error.call(options.context, xhr, textStatus, errorThrown);
+    };
+
+    // Make the request, allowing the user to override any Ajax options.
+    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
+    model.trigger('request', model, xhr, options);
+    return xhr;
+  };
+
+  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
+  var methodMap = {
+    'create': 'POST',
+    'update': 'PUT',
+    'patch': 'PATCH',
+    'delete': 'DELETE',
+    'read': 'GET'
+  };
+
+  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
+  // Override this if you'd like to use a different library.
+  Backbone.ajax = function() {
+    return Backbone.$.ajax.apply(Backbone.$, arguments);
+  };
+
+  // Backbone.Router
+  // ---------------
+
+  // Routers map faux-URLs to actions, and fire events when routes are
+  // matched. Creating a new one sets its `routes` hash, if not set statically.
+  var Router = Backbone.Router = function(options) {
+    options || (options = {});
+    if (options.routes) this.routes = options.routes;
+    this._bindRoutes();
+    this.initialize.apply(this, arguments);
+  };
+
+  // Cached regular expressions for matching named param parts and splatted
+  // parts of route strings.
+  var optionalParam = /\((.*?)\)/g;
+  var namedParam    = /(\(\?)?:\w+/g;
+  var splatParam    = /\*\w+/g;
+  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
+
+  // Set up all inheritable **Backbone.Router** properties and methods.
+  _.extend(Router.prototype, Events, {
+
+    // Initialize is an empty function by default. Override it with your own
+    // initialization logic.
+    initialize: function(){},
+
+    // Manually bind a single named route to a callback. For example:
+    //
+    //     this.route('search/:query/p:num', 'search', function(query, num) {
+    //       ...
+    //     });
+    //
+    route: function(route, name, callback) {
+      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
+      if (_.isFunction(name)) {
+        callback = name;
+        name = '';
+      }
+      if (!callback) callback = this[name];
+      var router = this;
+      Backbone.history.route(route, function(fragment) {
+        var args = router._extractParameters(route, fragment);
+        if (router.execute(callback, args, name) !== false) {
+          router.trigger.apply(router, ['route:' + name].concat(args));
+          router.trigger('route', name, args);
+          Backbone.history.trigger('route', router, name, args);
+        }
+      });
+      return this;
+    },
+
+    // Execute a route handler with the provided parameters.  This is an
+    // excellent place to do pre-route setup or post-route cleanup.
+    execute: function(callback, args, name) {
+      if (callback) callback.apply(this, args);
+    },
+
+    // Simple proxy to `Backbone.history` to save a fragment into the history.
+    navigate: function(fragment, options) {
+      Backbone.history.navigate(fragment, options);
+      return this;
+    },
+
+    // Bind all defined routes to `Backbone.history`. We have to reverse the
+    // order of the routes here to support behavior where the most general
+    // routes can be defined at the bottom of the route map.
+    _bindRoutes: function() {
+      if (!this.routes) return;
+      this.routes = _.result(this, 'routes');
+      var route, routes = _.keys(this.routes);
+      while ((route = routes.pop()) != null) {
+        this.route(route, this.routes[route]);
+      }
+    },
+
+    // Convert a route string into a regular expression, suitable for matching
+    // against the current location hash.
+    _routeToRegExp: function(route) {
+      route = route.replace(escapeRegExp, '\\$&')
+                   .replace(optionalParam, '(?:$1)?')
+                   .replace(namedParam, function(match, optional) {
+                     return optional ? match : '([^/?]+)';
+                   })
+                   .replace(splatParam, '([^?]*?)');
+      return new RegExp('^' + route + '(?:\\?([\\s\\S]*))?$');
+    },
+
+    // Given a route, and a URL fragment that it matches, return the array of
+    // extracted decoded parameters. Empty or unmatched parameters will be
+    // treated as `null` to normalize cross-browser behavior.
+    _extractParameters: function(route, fragment) {
+      var params = route.exec(fragment).slice(1);
+      return _.map(params, function(param, i) {
+        // Don't decode the search params.
+        if (i === params.length - 1) return param || null;
+        return param ? decodeURIComponent(param) : null;
+      });
+    }
+
+  });
+
+  // Backbone.History
+  // ----------------
+
+  // Handles cross-browser history management, based on either
+  // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
+  // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
+  // and URL fragments. If the browser supports neither (old IE, natch),
+  // falls back to polling.
+  var History = Backbone.History = function() {
+    this.handlers = [];
+    this.checkUrl = _.bind(this.checkUrl, this);
+
+    // Ensure that `History` can be used outside of the browser.
+    if (typeof window !== 'undefined') {
+      this.location = window.location;
+      this.history = window.history;
+    }
+  };
+
+  // Cached regex for stripping a leading hash/slash and trailing space.
+  var routeStripper = /^[#\/]|\s+$/g;
+
+  // Cached regex for stripping leading and trailing slashes.
+  var rootStripper = /^\/+|\/+$/g;
+
+  // Cached regex for stripping urls of hash.
+  var pathStripper = /#.*$/;
+
+  // Has the history handling already been started?
+  History.started = false;
+
+  // Set up all inheritable **Backbone.History** properties and methods.
+  _.extend(History.prototype, Events, {
+
+    // The default interval to poll for hash changes, if necessary, is
+    // twenty times a second.
+    interval: 50,
+
+    // Are we at the app root?
+    atRoot: function() {
+      var path = this.location.pathname.replace(/[^\/]$/, '$&/');
+      return path === this.root && !this.getSearch();
+    },
+
+    // Does the pathname match the root?
+    matchRoot: function() {
+      var path = this.decodeFragment(this.location.pathname);
+      var rootPath = path.slice(0, this.root.length - 1) + '/';
+      return rootPath === this.root;
+    },
+
+    // Unicode characters in `location.pathname` are percent encoded so they're
+    // decoded for comparison. `%25` should not be decoded since it may be part
+    // of an encoded parameter.
+    decodeFragment: function(fragment) {
+      return decodeURI(fragment.replace(/%25/g, '%2525'));
+    },
+
+    // In IE6, the hash fragment and search params are incorrect if the
+    // fragment contains `?`.
+    getSearch: function() {
+      var match = this.location.href.replace(/#.*/, '').match(/\?.+/);
+      return match ? match[0] : '';
+    },
+
+    // Gets the true hash value. Cannot use location.hash directly due to bug
+    // in Firefox where location.hash will always be decoded.
+    getHash: function(window) {
+      var match = (window || this).location.href.match(/#(.*)$/);
+      return match ? match[1] : '';
+    },
+
+    // Get the pathname and search params, without the root.
+    getPath: function() {
+      var path = this.decodeFragment(
+        this.location.pathname + this.getSearch()
+      ).slice(this.root.length - 1);
+      return path.charAt(0) === '/' ? path.slice(1) : path;
+    },
+
+    // Get the cross-browser normalized URL fragment from the path or hash.
+    getFragment: function(fragment) {
+      if (fragment == null) {
+        if (this._usePushState || !this._wantsHashChange) {
+          fragment = this.getPath();
+        } else {
+          fragment = this.getHash();
+        }
+      }
+      return fragment.replace(routeStripper, '');
+    },
+
+    // Start the hash change handling, returning `true` if the current URL matches
+    // an existing route, and `false` otherwise.
+    start: function(options) {
+      if (History.started) throw new Error('Backbone.history has already been started');
+      History.started = true;
+
+      // Figure out the initial configuration. Do we need an iframe?
+      // Is pushState desired ... is it available?
+      this.options          = _.extend({root: '/'}, this.options, options);
+      this.root             = this.options.root;
+      this._wantsHashChange = this.options.hashChange !== false;
+      this._hasHashChange   = 'onhashchange' in window && (document.documentMode === void 0 || document.documentMode > 7);
+      this._useHashChange   = this._wantsHashChange && this._hasHashChange;
+      this._wantsPushState  = !!this.options.pushState;
+      this._hasPushState    = !!(this.history && this.history.pushState);
+      this._usePushState    = this._wantsPushState && this._hasPushState;
+      this.fragment         = this.getFragment();
+
+      // Normalize root to always include a leading and trailing slash.
+      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
+
+      // Transition from hashChange to pushState or vice versa if both are
+      // requested.
+      if (this._wantsHashChange && this._wantsPushState) {
+
+        // If we've started off with a route from a `pushState`-enabled
+        // browser, but we're currently in a browser that doesn't support it...
+        if (!this._hasPushState && !this.atRoot()) {
+          var rootPath = this.root.slice(0, -1) || '/';
+          this.location.replace(rootPath + '#' + this.getPath());
+          // Return immediately as browser will do redirect to new url
+          return true;
+
+        // Or if we've started out with a hash-based route, but we're currently
+        // in a browser where it could be `pushState`-based instead...
+        } else if (this._hasPushState && this.atRoot()) {
+          this.navigate(this.getHash(), {replace: true});
+        }
+
+      }
+
+      // Proxy an iframe to handle location events if the browser doesn't
+      // support the `hashchange` event, HTML5 history, or the user wants
+      // `hashChange` but not `pushState`.
+      if (!this._hasHashChange && this._wantsHashChange && !this._usePushState) {
+        this.iframe = document.createElement('iframe');
+        this.iframe.src = 'javascript:0';
+        this.iframe.style.display = 'none';
+        this.iframe.tabIndex = -1;
+        var body = document.body;
+        // Using `appendChild` will throw on IE < 9 if the document is not ready.
+        var iWindow = body.insertBefore(this.iframe, body.firstChild).contentWindow;
+        iWindow.document.open();
+        iWindow.document.close();
+        iWindow.location.hash = '#' + this.fragment;
+      }
+
+      // Add a cross-platform `addEventListener` shim for older browsers.
+      var addEventListener = window.addEventListener || function(eventName, listener) {
+        return attachEvent('on' + eventName, listener);
+      };
+
+      // Depending on whether we're using pushState or hashes, and whether
+      // 'onhashchange' is supported, determine how we check the URL state.
+      if (this._usePushState) {
+        addEventListener('popstate', this.checkUrl, false);
+      } else if (this._useHashChange && !this.iframe) {
+        addEventListener('hashchange', this.checkUrl, false);
+      } else if (this._wantsHashChange) {
+        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
+      }
+
+      if (!this.options.silent) return this.loadUrl();
+    },
+
+    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
+    // but possibly useful for unit testing Routers.
+    stop: function() {
+      // Add a cross-platform `removeEventListener` shim for older browsers.
+      var removeEventListener = window.removeEventListener || function(eventName, listener) {
+        return detachEvent('on' + eventName, listener);
+      };
+
+      // Remove window listeners.
+      if (this._usePushState) {
+        removeEventListener('popstate', this.checkUrl, false);
+      } else if (this._useHashChange && !this.iframe) {
+        removeEventListener('hashchange', this.checkUrl, false);
+      }
+
+      // Clean up the iframe if necessary.
+      if (this.iframe) {
+        document.body.removeChild(this.iframe);
+        this.iframe = null;
+      }
+
+      // Some environments will throw when clearing an undefined interval.
+      if (this._checkUrlInterval) clearInterval(this._checkUrlInterval);
+      History.started = false;
+    },
+
+    // Add a route to be tested when the fragment changes. Routes added later
+    // may override previous routes.
+    route: function(route, callback) {
+      this.handlers.unshift({route: route, callback: callback});
+    },
+
+    // Checks the current URL to see if it has changed, and if it has,
+    // calls `loadUrl`, normalizing across the hidden iframe.
+    checkUrl: function(e) {
+      var current = this.getFragment();
+
+      // If the user pressed the back button, the iframe's hash will have
+      // changed and we should use that for comparison.
+      if (current === this.fragment && this.iframe) {
+        current = this.getHash(this.iframe.contentWindow);
+      }
+
+      if (current === this.fragment) return false;
+      if (this.iframe) this.navigate(current);
+      this.loadUrl();
+    },
+
+    // Attempt to load the current URL fragment. If a route succeeds with a
+    // match, returns `true`. If no defined routes matches the fragment,
+    // returns `false`.
+    loadUrl: function(fragment) {
+      // If the root doesn't match, no routes can match either.
+      if (!this.matchRoot()) return false;
+      fragment = this.fragment = this.getFragment(fragment);
+      return _.some(this.handlers, function(handler) {
+        if (handler.route.test(fragment)) {
+          handler.callback(fragment);
+          return true;
+        }
+      });
+    },
+
+    // Save a fragment into the hash history, or replace the URL state if the
+    // 'replace' option is passed. You are responsible for properly URL-encoding
+    // the fragment in advance.
+    //
+    // The options object can contain `trigger: true` if you wish to have the
+    // route callback be fired (not usually desirable), or `replace: true`, if
+    // you wish to modify the current URL without adding an entry to the history.
+    navigate: function(fragment, options) {
+      if (!History.started) return false;
+      if (!options || options === true) options = {trigger: !!options};
+
+      // Normalize the fragment.
+      fragment = this.getFragment(fragment || '');
+
+      // Don't include a trailing slash on the root.
+      var rootPath = this.root;
+      if (fragment === '' || fragment.charAt(0) === '?') {
+        rootPath = rootPath.slice(0, -1) || '/';
+      }
+      var url = rootPath + fragment;
+
+      // Strip the hash and decode for matching.
+      fragment = this.decodeFragment(fragment.replace(pathStripper, ''));
+
+      if (this.fragment === fragment) return;
+      this.fragment = fragment;
+
+      // If pushState is available, we use it to set the fragment as a real URL.
+      if (this._usePushState) {
+        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
+
+      // If hash changes haven't been explicitly disabled, update the hash
+      // fragment to store history.
+      } else if (this._wantsHashChange) {
+        this._updateHash(this.location, fragment, options.replace);
+        if (this.iframe && fragment !== this.getHash(this.iframe.contentWindow)) {
+          var iWindow = this.iframe.contentWindow;
+
+          // Opening and closing the iframe tricks IE7 and earlier to push a
+          // history entry on hash-tag change.  When replace is true, we don't
+          // want this.
+          if (!options.replace) {
+            iWindow.document.open();
+            iWindow.document.close();
+          }
+
+          this._updateHash(iWindow.location, fragment, options.replace);
+        }
+
+      // If you've told us that you explicitly don't want fallback hashchange-
+      // based history, then `navigate` becomes a page refresh.
+      } else {
+        return this.location.assign(url);
+      }
+      if (options.trigger) return this.loadUrl(fragment);
+    },
+
+    // Update the hash location, either replacing the current entry, or adding
+    // a new one to the browser history.
+    _updateHash: function(location, fragment, replace) {
+      if (replace) {
+        var href = location.href.replace(/(javascript:|#).*$/, '');
+        location.replace(href + '#' + fragment);
+      } else {
+        // Some browsers require that `hash` contains a leading #.
+        location.hash = '#' + fragment;
+      }
+    }
+
+  });
+
+  // Create the default Backbone.history.
+  Backbone.history = new History;
+
+  // Helpers
+  // -------
+
+  // Helper function to correctly set up the prototype chain for subclasses.
+  // Similar to `goog.inherits`, but uses a hash of prototype properties and
+  // class properties to be extended.
+  var extend = function(protoProps, staticProps) {
+    var parent = this;
+    var child;
+
+    // The constructor function for the new subclass is either defined by you
+    // (the "constructor" property in your `extend` definition), or defaulted
+    // by us to simply call the parent constructor.
+    if (protoProps && _.has(protoProps, 'constructor')) {
+      child = protoProps.constructor;
+    } else {
+      child = function(){ return parent.apply(this, arguments); };
+    }
+
+    // Add static properties to the constructor function, if supplied.
+    _.extend(child, parent, staticProps);
+
+    // Set the prototype chain to inherit from `parent`, without calling
+    // `parent`'s constructor function and add the prototype properties.
+    child.prototype = _.create(parent.prototype, protoProps);
+    child.prototype.constructor = child;
+
+    // Set a convenience property in case the parent's prototype is needed
+    // later.
+    child.__super__ = parent.prototype;
+
+    return child;
+  };
+
+  // Set up inheritance for the model, collection, router, view and history.
+  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
+
+  // Throw an error when a URL is needed, and none is supplied.
+  var urlError = function() {
+    throw new Error('A "url" property or function must be specified');
+  };
+
+  // Wrap an optional error callback with a fallback error event.
+  var wrapError = function(model, options) {
+    var error = options.error;
+    options.error = function(resp) {
+      if (error) error.call(options.context, model, resp, options);
+      model.trigger('error', model, resp, options);
+    };
+  };
+
+  return Backbone;
+});
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/collection.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/collection.js
new file mode 100644
index 0000000..dd98aca
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/collection.js
@@ -0,0 +1,1998 @@
+(function() {
+
+  var a, b, c, d, e, col, otherCol;
+
+  QUnit.module('Backbone.Collection', {
+
+    beforeEach: function(assert) {
+      a         = new Backbone.Model({id: 3, label: 'a'});
+      b         = new Backbone.Model({id: 2, label: 'b'});
+      c         = new Backbone.Model({id: 1, label: 'c'});
+      d         = new Backbone.Model({id: 0, label: 'd'});
+      e         = null;
+      col       = new Backbone.Collection([a, b, c, d]);
+      otherCol  = new Backbone.Collection();
+    }
+
+  });
+
+  QUnit.test('new and sort', function(assert) {
+    assert.expect(6);
+    var counter = 0;
+    col.on('sort', function(){ counter++; });
+    assert.deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);
+    col.comparator = function(m1, m2) {
+      return m1.id > m2.id ? -1 : 1;
+    };
+    col.sort();
+    assert.equal(counter, 1);
+    assert.deepEqual(col.pluck('label'), ['a', 'b', 'c', 'd']);
+    col.comparator = function(model) { return model.id; };
+    col.sort();
+    assert.equal(counter, 2);
+    assert.deepEqual(col.pluck('label'), ['d', 'c', 'b', 'a']);
+    assert.equal(col.length, 4);
+  });
+
+  QUnit.test('String comparator.', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([
+      {id: 3},
+      {id: 1},
+      {id: 2}
+    ], {comparator: 'id'});
+    assert.deepEqual(collection.pluck('id'), [1, 2, 3]);
+  });
+
+  QUnit.test('new and parse', function(assert) {
+    assert.expect(3);
+    var Collection = Backbone.Collection.extend({
+      parse: function(data) {
+        return _.filter(data, function(datum) {
+          return datum.a % 2 === 0;
+        });
+      }
+    });
+    var models = [{a: 1}, {a: 2}, {a: 3}, {a: 4}];
+    var collection = new Collection(models, {parse: true});
+    assert.strictEqual(collection.length, 2);
+    assert.strictEqual(collection.first().get('a'), 2);
+    assert.strictEqual(collection.last().get('a'), 4);
+  });
+
+  QUnit.test('clone preserves model and comparator', function(assert) {
+    assert.expect(3);
+    var Model = Backbone.Model.extend();
+    var comparator = function(model){ return model.id; };
+
+    var collection = new Backbone.Collection([{id: 1}], {
+      model: Model,
+      comparator: comparator
+    }).clone();
+    collection.add({id: 2});
+    assert.ok(collection.at(0) instanceof Model);
+    assert.ok(collection.at(1) instanceof Model);
+    assert.strictEqual(collection.comparator, comparator);
+  });
+
+  QUnit.test('get', function(assert) {
+    assert.expect(6);
+    assert.equal(col.get(0), d);
+    assert.equal(col.get(d.clone()), d);
+    assert.equal(col.get(2), b);
+    assert.equal(col.get({id: 1}), c);
+    assert.equal(col.get(c.clone()), c);
+    assert.equal(col.get(col.first().cid), col.first());
+  });
+
+  QUnit.test('get with non-default ids', function(assert) {
+    assert.expect(5);
+    var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
+    var model = new MongoModel({_id: 100});
+    var collection = new Backbone.Collection([model], {model: MongoModel});
+    assert.equal(collection.get(100), model);
+    assert.equal(collection.get(model.cid), model);
+    assert.equal(collection.get(model), model);
+    assert.equal(collection.get(101), void 0);
+
+    var collection2 = new Backbone.Collection();
+    collection2.model = MongoModel;
+    collection2.add(model.attributes);
+    assert.equal(collection2.get(model.clone()), collection2.first());
+  });
+
+  QUnit.test('has', function(assert) {
+    assert.expect(15);
+    assert.ok(col.has(a));
+    assert.ok(col.has(b));
+    assert.ok(col.has(c));
+    assert.ok(col.has(d));
+    assert.ok(col.has(a.id));
+    assert.ok(col.has(b.id));
+    assert.ok(col.has(c.id));
+    assert.ok(col.has(d.id));
+    assert.ok(col.has(a.cid));
+    assert.ok(col.has(b.cid));
+    assert.ok(col.has(c.cid));
+    assert.ok(col.has(d.cid));
+    var outsider = new Backbone.Model({id: 4});
+    assert.notOk(col.has(outsider));
+    assert.notOk(col.has(outsider.id));
+    assert.notOk(col.has(outsider.cid));
+  });
+
+  QUnit.test('update index when id changes', function(assert) {
+    assert.expect(4);
+    var collection = new Backbone.Collection();
+    collection.add([
+      {id: 0, name: 'one'},
+      {id: 1, name: 'two'}
+    ]);
+    var one = collection.get(0);
+    assert.equal(one.get('name'), 'one');
+    collection.on('change:name', function(model) { assert.ok(this.get(model)); });
+    one.set({name: 'dalmatians', id: 101});
+    assert.equal(collection.get(0), null);
+    assert.equal(collection.get(101).get('name'), 'dalmatians');
+  });
+
+  QUnit.test('at', function(assert) {
+    assert.expect(2);
+    assert.equal(col.at(2), c);
+    assert.equal(col.at(-2), c);
+  });
+
+  QUnit.test('pluck', function(assert) {
+    assert.expect(1);
+    assert.equal(col.pluck('label').join(' '), 'a b c d');
+  });
+
+  QUnit.test('add', function(assert) {
+    assert.expect(14);
+    var added, opts, secondAdded;
+    added = opts = secondAdded = null;
+    e = new Backbone.Model({id: 10, label: 'e'});
+    otherCol.add(e);
+    otherCol.on('add', function() {
+      secondAdded = true;
+    });
+    col.on('add', function(model, collection, options){
+      added = model.get('label');
+      opts = options;
+    });
+    col.add(e, {amazing: true});
+    assert.equal(added, 'e');
+    assert.equal(col.length, 5);
+    assert.equal(col.last(), e);
+    assert.equal(otherCol.length, 1);
+    assert.equal(secondAdded, null);
+    assert.ok(opts.amazing);
+
+    var f = new Backbone.Model({id: 20, label: 'f'});
+    var g = new Backbone.Model({id: 21, label: 'g'});
+    var h = new Backbone.Model({id: 22, label: 'h'});
+    var atCol = new Backbone.Collection([f, g, h]);
+    assert.equal(atCol.length, 3);
+    atCol.add(e, {at: 1});
+    assert.equal(atCol.length, 4);
+    assert.equal(atCol.at(1), e);
+    assert.equal(atCol.last(), h);
+
+    var coll = new Backbone.Collection(new Array(2));
+    var addCount = 0;
+    coll.on('add', function(){
+      addCount += 1;
+    });
+    coll.add([undefined, f, g]);
+    assert.equal(coll.length, 5);
+    assert.equal(addCount, 3);
+    coll.add(new Array(4));
+    assert.equal(coll.length, 9);
+    assert.equal(addCount, 7);
+  });
+
+  QUnit.test('add multiple models', function(assert) {
+    assert.expect(6);
+    var collection = new Backbone.Collection([{at: 0}, {at: 1}, {at: 9}]);
+    collection.add([{at: 2}, {at: 3}, {at: 4}, {at: 5}, {at: 6}, {at: 7}, {at: 8}], {at: 2});
+    for (var i = 0; i <= 5; i++) {
+      assert.equal(collection.at(i).get('at'), i);
+    }
+  });
+
+  QUnit.test('add; at should have preference over comparator', function(assert) {
+    assert.expect(1);
+    var Col = Backbone.Collection.extend({
+      comparator: function(m1, m2) {
+        return m1.id > m2.id ? -1 : 1;
+      }
+    });
+
+    var collection = new Col([{id: 2}, {id: 3}]);
+    collection.add(new Backbone.Model({id: 1}), {at: 1});
+
+    assert.equal(collection.pluck('id').join(' '), '3 1 2');
+  });
+
+  QUnit.test('add; at should add to the end if the index is out of bounds', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 2}, {id: 3}]);
+    collection.add(new Backbone.Model({id: 1}), {at: 5});
+
+    assert.equal(collection.pluck('id').join(' '), '2 3 1');
+  });
+
+  QUnit.test("can't add model to collection twice", function(assert) {
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 1}, {id: 2}, {id: 3}]);
+    assert.equal(collection.pluck('id').join(' '), '1 2 3');
+  });
+
+  QUnit.test("can't add different model with same id to collection twice", function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection;
+    collection.unshift({id: 101});
+    collection.add({id: 101});
+    assert.equal(collection.length, 1);
+  });
+
+  QUnit.test('merge in duplicate models with {merge: true}', function(assert) {
+    assert.expect(3);
+    var collection = new Backbone.Collection;
+    collection.add([{id: 1, name: 'Moe'}, {id: 2, name: 'Curly'}, {id: 3, name: 'Larry'}]);
+    collection.add({id: 1, name: 'Moses'});
+    assert.equal(collection.first().get('name'), 'Moe');
+    collection.add({id: 1, name: 'Moses'}, {merge: true});
+    assert.equal(collection.first().get('name'), 'Moses');
+    collection.add({id: 1, name: 'Tim'}, {merge: true, silent: true});
+    assert.equal(collection.first().get('name'), 'Tim');
+  });
+
+  QUnit.test('add model to multiple collections', function(assert) {
+    assert.expect(10);
+    var counter = 0;
+    var m = new Backbone.Model({id: 10, label: 'm'});
+    m.on('add', function(model, collection) {
+      counter++;
+      assert.equal(m, model);
+      if (counter > 1) {
+        assert.equal(collection, col2);
+      } else {
+        assert.equal(collection, col1);
+      }
+    });
+    var col1 = new Backbone.Collection([]);
+    col1.on('add', function(model, collection) {
+      assert.equal(m, model);
+      assert.equal(col1, collection);
+    });
+    var col2 = new Backbone.Collection([]);
+    col2.on('add', function(model, collection) {
+      assert.equal(m, model);
+      assert.equal(col2, collection);
+    });
+    col1.add(m);
+    assert.equal(m.collection, col1);
+    col2.add(m);
+    assert.equal(m.collection, col1);
+  });
+
+  QUnit.test('add model with parse', function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      parse: function(obj) {
+        obj.value += 1;
+        return obj;
+      }
+    });
+
+    var Col = Backbone.Collection.extend({model: Model});
+    var collection = new Col;
+    collection.add({value: 1}, {parse: true});
+    assert.equal(collection.at(0).get('value'), 2);
+  });
+
+  QUnit.test('add with parse and merge', function(assert) {
+    var collection = new Backbone.Collection();
+    collection.parse = function(attrs) {
+      return _.map(attrs, function(model) {
+        if (model.model) return model.model;
+        return model;
+      });
+    };
+    collection.add({id: 1});
+    collection.add({model: {id: 1, name: 'Alf'}}, {parse: true, merge: true});
+    assert.equal(collection.first().get('name'), 'Alf');
+  });
+
+  QUnit.test('add model to collection with sort()-style comparator', function(assert) {
+    assert.expect(3);
+    var collection = new Backbone.Collection;
+    collection.comparator = function(m1, m2) {
+      return m1.get('name') < m2.get('name') ? -1 : 1;
+    };
+    var tom = new Backbone.Model({name: 'Tom'});
+    var rob = new Backbone.Model({name: 'Rob'});
+    var tim = new Backbone.Model({name: 'Tim'});
+    collection.add(tom);
+    collection.add(rob);
+    collection.add(tim);
+    assert.equal(collection.indexOf(rob), 0);
+    assert.equal(collection.indexOf(tim), 1);
+    assert.equal(collection.indexOf(tom), 2);
+  });
+
+  QUnit.test('comparator that depends on `this`', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection;
+    collection.negative = function(num) {
+      return -num;
+    };
+    collection.comparator = function(model) {
+      return this.negative(model.id);
+    };
+    collection.add([{id: 1}, {id: 2}, {id: 3}]);
+    assert.deepEqual(collection.pluck('id'), [3, 2, 1]);
+    collection.comparator = function(m1, m2) {
+      return this.negative(m2.id) - this.negative(m1.id);
+    };
+    collection.sort();
+    assert.deepEqual(collection.pluck('id'), [1, 2, 3]);
+  });
+
+  QUnit.test('remove', function(assert) {
+    assert.expect(12);
+    var removed = null;
+    var result = null;
+    col.on('remove', function(model, collection, options) {
+      removed = model.get('label');
+      assert.equal(options.index, 3);
+      assert.equal(collection.get(model), undefined, '#3693: model cannot be fetched from collection');
+    });
+    result = col.remove(d);
+    assert.equal(removed, 'd');
+    assert.strictEqual(result, d);
+    //if we try to remove d again, it's not going to actually get removed
+    result = col.remove(d);
+    assert.strictEqual(result, undefined);
+    assert.equal(col.length, 3);
+    assert.equal(col.first(), a);
+    col.off();
+    result = col.remove([c, d]);
+    assert.equal(result.length, 1, 'only returns removed models');
+    assert.equal(result[0], c, 'only returns removed models');
+    result = col.remove([c, b]);
+    assert.equal(result.length, 1, 'only returns removed models');
+    assert.equal(result[0], b, 'only returns removed models');
+    result = col.remove([]);
+    assert.deepEqual(result, [], 'returns empty array when nothing removed');
+  });
+
+  QUnit.test('add and remove return values', function(assert) {
+    assert.expect(13);
+    var Even = Backbone.Model.extend({
+      validate: function(attrs) {
+        if (attrs.id % 2 !== 0) return 'odd';
+      }
+    });
+    var collection = new Backbone.Collection;
+    collection.model = Even;
+
+    var list = collection.add([{id: 2}, {id: 4}], {validate: true});
+    assert.equal(list.length, 2);
+    assert.ok(list[0] instanceof Backbone.Model);
+    assert.equal(list[1], collection.last());
+    assert.equal(list[1].get('id'), 4);
+
+    list = collection.add([{id: 3}, {id: 6}], {validate: true});
+    assert.equal(collection.length, 3);
+    assert.equal(list[0], false);
+    assert.equal(list[1].get('id'), 6);
+
+    var result = collection.add({id: 6});
+    assert.equal(result.cid, list[1].cid);
+
+    result = collection.remove({id: 6});
+    assert.equal(collection.length, 2);
+    assert.equal(result.id, 6);
+
+    list = collection.remove([{id: 2}, {id: 8}]);
+    assert.equal(collection.length, 1);
+    assert.equal(list[0].get('id'), 2);
+    assert.equal(list[1], null);
+  });
+
+  QUnit.test('shift and pop', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
+    assert.equal(collection.shift().get('a'), 'a');
+    assert.equal(collection.pop().get('c'), 'c');
+  });
+
+  QUnit.test('slice', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection([{a: 'a'}, {b: 'b'}, {c: 'c'}]);
+    var array = collection.slice(1, 3);
+    assert.equal(array.length, 2);
+    assert.equal(array[0].get('b'), 'b');
+  });
+
+  QUnit.test('events are unbound on remove', function(assert) {
+    assert.expect(3);
+    var counter = 0;
+    var dj = new Backbone.Model();
+    var emcees = new Backbone.Collection([dj]);
+    emcees.on('change', function(){ counter++; });
+    dj.set({name: 'Kool'});
+    assert.equal(counter, 1);
+    emcees.reset([]);
+    assert.equal(dj.collection, undefined);
+    dj.set({name: 'Shadow'});
+    assert.equal(counter, 1);
+  });
+
+  QUnit.test('remove in multiple collections', function(assert) {
+    assert.expect(7);
+    var modelData = {
+      id: 5,
+      title: 'Othello'
+    };
+    var passed = false;
+    var m1 = new Backbone.Model(modelData);
+    var m2 = new Backbone.Model(modelData);
+    m2.on('remove', function() {
+      passed = true;
+    });
+    var col1 = new Backbone.Collection([m1]);
+    var col2 = new Backbone.Collection([m2]);
+    assert.notEqual(m1, m2);
+    assert.ok(col1.length === 1);
+    assert.ok(col2.length === 1);
+    col1.remove(m1);
+    assert.equal(passed, false);
+    assert.ok(col1.length === 0);
+    col2.remove(m1);
+    assert.ok(col2.length === 0);
+    assert.equal(passed, true);
+  });
+
+  QUnit.test('remove same model in multiple collection', function(assert) {
+    assert.expect(16);
+    var counter = 0;
+    var m = new Backbone.Model({id: 5, title: 'Othello'});
+    m.on('remove', function(model, collection) {
+      counter++;
+      assert.equal(m, model);
+      if (counter > 1) {
+        assert.equal(collection, col1);
+      } else {
+        assert.equal(collection, col2);
+      }
+    });
+    var col1 = new Backbone.Collection([m]);
+    col1.on('remove', function(model, collection) {
+      assert.equal(m, model);
+      assert.equal(col1, collection);
+    });
+    var col2 = new Backbone.Collection([m]);
+    col2.on('remove', function(model, collection) {
+      assert.equal(m, model);
+      assert.equal(col2, collection);
+    });
+    assert.equal(col1, m.collection);
+    col2.remove(m);
+    assert.ok(col2.length === 0);
+    assert.ok(col1.length === 1);
+    assert.equal(counter, 1);
+    assert.equal(col1, m.collection);
+    col1.remove(m);
+    assert.equal(null, m.collection);
+    assert.ok(col1.length === 0);
+    assert.equal(counter, 2);
+  });
+
+  QUnit.test('model destroy removes from all collections', function(assert) {
+    assert.expect(3);
+    var m = new Backbone.Model({id: 5, title: 'Othello'});
+    m.sync = function(method, model, options) { options.success(); };
+    var col1 = new Backbone.Collection([m]);
+    var col2 = new Backbone.Collection([m]);
+    m.destroy();
+    assert.ok(col1.length === 0);
+    assert.ok(col2.length === 0);
+    assert.equal(undefined, m.collection);
+  });
+
+  QUnit.test('Collection: non-persisted model destroy removes from all collections', function(assert) {
+    assert.expect(3);
+    var m = new Backbone.Model({title: 'Othello'});
+    m.sync = function(method, model, options) { throw 'should not be called'; };
+    var col1 = new Backbone.Collection([m]);
+    var col2 = new Backbone.Collection([m]);
+    m.destroy();
+    assert.ok(col1.length === 0);
+    assert.ok(col2.length === 0);
+    assert.equal(undefined, m.collection);
+  });
+
+  QUnit.test('fetch', function(assert) {
+    assert.expect(4);
+    var collection = new Backbone.Collection;
+    collection.url = '/test';
+    collection.fetch();
+    assert.equal(this.syncArgs.method, 'read');
+    assert.equal(this.syncArgs.model, collection);
+    assert.equal(this.syncArgs.options.parse, true);
+
+    collection.fetch({parse: false});
+    assert.equal(this.syncArgs.options.parse, false);
+  });
+
+  QUnit.test('fetch with an error response triggers an error event', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection();
+    collection.on('error', function() {
+      assert.ok(true);
+    });
+    collection.sync = function(method, model, options) { options.error(); };
+    collection.fetch();
+  });
+
+  QUnit.test('#3283 - fetch with an error response calls error with context', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection();
+    var obj = {};
+    var options = {
+      context: obj,
+      error: function() {
+        assert.equal(this, obj);
+      }
+    };
+    collection.sync = function(method, model, opts) {
+      opts.error.call(opts.context);
+    };
+    collection.fetch(options);
+  });
+
+  QUnit.test('ensure fetch only parses once', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection;
+    var counter = 0;
+    collection.parse = function(models) {
+      counter++;
+      return models;
+    };
+    collection.url = '/test';
+    collection.fetch();
+    this.syncArgs.options.success([]);
+    assert.equal(counter, 1);
+  });
+
+  QUnit.test('create', function(assert) {
+    assert.expect(4);
+    var collection = new Backbone.Collection;
+    collection.url = '/test';
+    var model = collection.create({label: 'f'}, {wait: true});
+    assert.equal(this.syncArgs.method, 'create');
+    assert.equal(this.syncArgs.model, model);
+    assert.equal(model.get('label'), 'f');
+    assert.equal(model.collection, collection);
+  });
+
+  QUnit.test('create with validate:true enforces validation', function(assert) {
+    assert.expect(3);
+    var ValidatingModel = Backbone.Model.extend({
+      validate: function(attrs) {
+        return 'fail';
+      }
+    });
+    var ValidatingCollection = Backbone.Collection.extend({
+      model: ValidatingModel
+    });
+    var collection = new ValidatingCollection();
+    collection.on('invalid', function(coll, error, options) {
+      assert.equal(error, 'fail');
+      assert.equal(options.validationError, 'fail');
+    });
+    assert.equal(collection.create({'foo': 'bar'}, {validate: true}), false);
+  });
+
+  QUnit.test('create will pass extra options to success callback', function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      sync: function(method, model, options) {
+        _.extend(options, {specialSync: true});
+        return Backbone.Model.prototype.sync.call(this, method, model, options);
+      }
+    });
+
+    var Collection = Backbone.Collection.extend({
+      model: Model,
+      url: '/test'
+    });
+
+    var collection = new Collection;
+
+    var success = function(model, response, options) {
+      assert.ok(options.specialSync, 'Options were passed correctly to callback');
+    };
+
+    collection.create({}, {success: success});
+    this.ajaxSettings.success();
+  });
+
+  QUnit.test('create with wait:true should not call collection.parse', function(assert) {
+    assert.expect(0);
+    var Collection = Backbone.Collection.extend({
+      url: '/test',
+      parse: function() {
+        assert.ok(false);
+      }
+    });
+
+    var collection = new Collection;
+
+    collection.create({}, {wait: true});
+    this.ajaxSettings.success();
+  });
+
+  QUnit.test('a failing create returns model with errors', function(assert) {
+    var ValidatingModel = Backbone.Model.extend({
+      validate: function(attrs) {
+        return 'fail';
+      }
+    });
+    var ValidatingCollection = Backbone.Collection.extend({
+      model: ValidatingModel
+    });
+    var collection = new ValidatingCollection();
+    var m = collection.create({foo: 'bar'});
+    assert.equal(m.validationError, 'fail');
+    assert.equal(collection.length, 1);
+  });
+
+  QUnit.test('initialize', function(assert) {
+    assert.expect(1);
+    var Collection = Backbone.Collection.extend({
+      initialize: function() {
+        this.one = 1;
+      }
+    });
+    var coll = new Collection;
+    assert.equal(coll.one, 1);
+  });
+
+  QUnit.test('toJSON', function(assert) {
+    assert.expect(1);
+    assert.equal(JSON.stringify(col), '[{"id":3,"label":"a"},{"id":2,"label":"b"},{"id":1,"label":"c"},{"id":0,"label":"d"}]');
+  });
+
+  QUnit.test('where and findWhere', function(assert) {
+    assert.expect(8);
+    var model = new Backbone.Model({a: 1});
+    var coll = new Backbone.Collection([
+      model,
+      {a: 1},
+      {a: 1, b: 2},
+      {a: 2, b: 2},
+      {a: 3}
+    ]);
+    assert.equal(coll.where({a: 1}).length, 3);
+    assert.equal(coll.where({a: 2}).length, 1);
+    assert.equal(coll.where({a: 3}).length, 1);
+    assert.equal(coll.where({b: 1}).length, 0);
+    assert.equal(coll.where({b: 2}).length, 2);
+    assert.equal(coll.where({a: 1, b: 2}).length, 1);
+    assert.equal(coll.findWhere({a: 1}), model);
+    assert.equal(coll.findWhere({a: 4}), void 0);
+  });
+
+  QUnit.test('Underscore methods', function(assert) {
+    assert.expect(21);
+    assert.equal(col.map(function(model){ return model.get('label'); }).join(' '), 'a b c d');
+    assert.equal(col.some(function(model){ return model.id === 100; }), false);
+    assert.equal(col.some(function(model){ return model.id === 0; }), true);
+    assert.equal(col.reduce(function(m1, m2) {return m1.id > m2.id ? m1 : m2;}).id, 3);
+    assert.equal(col.reduceRight(function(m1, m2) {return m1.id > m2.id ? m1 : m2;}).id, 3);
+    assert.equal(col.indexOf(b), 1);
+    assert.equal(col.size(), 4);
+    assert.equal(col.rest().length, 3);
+    assert.ok(!_.includes(col.rest(), a));
+    assert.ok(_.includes(col.rest(), d));
+    assert.ok(!col.isEmpty());
+    assert.ok(!_.includes(col.without(d), d));
+
+    var wrapped = col.chain();
+    assert.equal(wrapped.map('id').max().value(), 3);
+    assert.equal(wrapped.map('id').min().value(), 0);
+    assert.deepEqual(wrapped
+      .filter(function(o){ return o.id % 2 === 0; })
+      .map(function(o){ return o.id * 2; })
+      .value(),
+      [4, 0]);
+    assert.deepEqual(col.difference([c, d]), [a, b]);
+    assert.ok(col.includes(col.sample()));
+
+    var first = col.first();
+    assert.deepEqual(col.groupBy(function(model){ return model.id; })[first.id], [first]);
+    assert.deepEqual(col.countBy(function(model){ return model.id; }), {0: 1, 1: 1, 2: 1, 3: 1});
+    assert.deepEqual(col.sortBy(function(model){ return model.id; })[0], col.at(3));
+    assert.ok(col.indexBy('id')[first.id] === first);
+  });
+
+  QUnit.test('Underscore methods with object-style and property-style iteratee', function(assert) {
+    assert.expect(26);
+    var model = new Backbone.Model({a: 4, b: 1, e: 3});
+    var coll = new Backbone.Collection([
+      {a: 1, b: 1},
+      {a: 2, b: 1, c: 1},
+      {a: 3, b: 1},
+      model
+    ]);
+    assert.equal(coll.find({a: 0}), undefined);
+    assert.deepEqual(coll.find({a: 4}), model);
+    assert.equal(coll.find('d'), undefined);
+    assert.deepEqual(coll.find('e'), model);
+    assert.equal(coll.filter({a: 0}), false);
+    assert.deepEqual(coll.filter({a: 4}), [model]);
+    assert.equal(coll.some({a: 0}), false);
+    assert.equal(coll.some({a: 1}), true);
+    assert.equal(coll.reject({a: 0}).length, 4);
+    assert.deepEqual(coll.reject({a: 4}), _.without(coll.models, model));
+    assert.equal(coll.every({a: 0}), false);
+    assert.equal(coll.every({b: 1}), true);
+    assert.deepEqual(coll.partition({a: 0})[0], []);
+    assert.deepEqual(coll.partition({a: 0})[1], coll.models);
+    assert.deepEqual(coll.partition({a: 4})[0], [model]);
+    assert.deepEqual(coll.partition({a: 4})[1], _.without(coll.models, model));
+    assert.deepEqual(coll.map({a: 2}), [false, true, false, false]);
+    assert.deepEqual(coll.map('a'), [1, 2, 3, 4]);
+    assert.deepEqual(coll.sortBy('a')[3], model);
+    assert.deepEqual(coll.sortBy('e')[0], model);
+    assert.deepEqual(coll.countBy({a: 4}), {'false': 3, 'true': 1});
+    assert.deepEqual(coll.countBy('d'), {'undefined': 4});
+    assert.equal(coll.findIndex({b: 1}), 0);
+    assert.equal(coll.findIndex({b: 9}), -1);
+    assert.equal(coll.findLastIndex({b: 1}), 3);
+    assert.equal(coll.findLastIndex({b: 9}), -1);
+  });
+
+  QUnit.test('reset', function(assert) {
+    assert.expect(16);
+
+    var resetCount = 0;
+    var models = col.models;
+    col.on('reset', function() { resetCount += 1; });
+    col.reset([]);
+    assert.equal(resetCount, 1);
+    assert.equal(col.length, 0);
+    assert.equal(col.last(), null);
+    col.reset(models);
+    assert.equal(resetCount, 2);
+    assert.equal(col.length, 4);
+    assert.equal(col.last(), d);
+    col.reset(_.map(models, function(m){ return m.attributes; }));
+    assert.equal(resetCount, 3);
+    assert.equal(col.length, 4);
+    assert.ok(col.last() !== d);
+    assert.ok(_.isEqual(col.last().attributes, d.attributes));
+    col.reset();
+    assert.equal(col.length, 0);
+    assert.equal(resetCount, 4);
+
+    var f = new Backbone.Model({id: 20, label: 'f'});
+    col.reset([undefined, f]);
+    assert.equal(col.length, 2);
+    assert.equal(resetCount, 5);
+
+    col.reset(new Array(4));
+    assert.equal(col.length, 4);
+    assert.equal(resetCount, 6);
+  });
+
+  QUnit.test('reset with different values', function(assert) {
+    var collection = new Backbone.Collection({id: 1});
+    collection.reset({id: 1, a: 1});
+    assert.equal(collection.get(1).get('a'), 1);
+  });
+
+  QUnit.test('same references in reset', function(assert) {
+    var model = new Backbone.Model({id: 1});
+    var collection = new Backbone.Collection({id: 1});
+    collection.reset(model);
+    assert.equal(collection.get(1), model);
+  });
+
+  QUnit.test('reset passes caller options', function(assert) {
+    assert.expect(3);
+    var Model = Backbone.Model.extend({
+      initialize: function(attrs, options) {
+        this.modelParameter = options.modelParameter;
+      }
+    });
+    var collection = new (Backbone.Collection.extend({model: Model}))();
+    collection.reset([{astring: 'green', anumber: 1}, {astring: 'blue', anumber: 2}], {modelParameter: 'model parameter'});
+    assert.equal(collection.length, 2);
+    collection.each(function(model) {
+      assert.equal(model.modelParameter, 'model parameter');
+    });
+  });
+
+  QUnit.test('reset does not alter options by reference', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection([{id: 1}]);
+    var origOpts = {};
+    collection.on('reset', function(coll, opts){
+      assert.equal(origOpts.previousModels, undefined);
+      assert.equal(opts.previousModels[0].id, 1);
+    });
+    collection.reset([], origOpts);
+  });
+
+  QUnit.test('trigger custom events on models', function(assert) {
+    assert.expect(1);
+    var fired = null;
+    a.on('custom', function() { fired = true; });
+    a.trigger('custom');
+    assert.equal(fired, true);
+  });
+
+  QUnit.test('add does not alter arguments', function(assert) {
+    assert.expect(2);
+    var attrs = {};
+    var models = [attrs];
+    new Backbone.Collection().add(models);
+    assert.equal(models.length, 1);
+    assert.ok(attrs === models[0]);
+  });
+
+  QUnit.test('#714: access `model.collection` in a brand new model.', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection;
+    collection.url = '/test';
+    var Model = Backbone.Model.extend({
+      set: function(attrs) {
+        assert.equal(attrs.prop, 'value');
+        assert.equal(this.collection, collection);
+        return this;
+      }
+    });
+    collection.model = Model;
+    collection.create({prop: 'value'});
+  });
+
+  QUnit.test('#574, remove its own reference to the .models array.', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection([
+      {id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}
+    ]);
+    assert.equal(collection.length, 6);
+    collection.remove(collection.models);
+    assert.equal(collection.length, 0);
+  });
+
+  QUnit.test('#861, adding models to a collection which do not pass validation, with validate:true', function(assert) {
+    assert.expect(2);
+    var Model = Backbone.Model.extend({
+      validate: function(attrs) {
+        if (attrs.id === 3) return "id can't be 3";
+      }
+    });
+
+    var Collection = Backbone.Collection.extend({
+      model: Model
+    });
+
+    var collection = new Collection;
+    collection.on('invalid', function() { assert.ok(true); });
+
+    collection.add([{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}, {id: 6}], {validate: true});
+    assert.deepEqual(collection.pluck('id'), [1, 2, 4, 5, 6]);
+  });
+
+  QUnit.test('Invalid models are discarded with validate:true.', function(assert) {
+    assert.expect(5);
+    var collection = new Backbone.Collection;
+    collection.on('test', function() { assert.ok(true); });
+    collection.model = Backbone.Model.extend({
+      validate: function(attrs){ if (!attrs.valid) return 'invalid'; }
+    });
+    var model = new collection.model({id: 1, valid: true});
+    collection.add([model, {id: 2}], {validate: true});
+    model.trigger('test');
+    assert.ok(collection.get(model.cid));
+    assert.ok(collection.get(1));
+    assert.ok(!collection.get(2));
+    assert.equal(collection.length, 1);
+  });
+
+  QUnit.test('multiple copies of the same model', function(assert) {
+    assert.expect(3);
+    var collection = new Backbone.Collection();
+    var model = new Backbone.Model();
+    collection.add([model, model]);
+    assert.equal(collection.length, 1);
+    collection.add([{id: 1}, {id: 1}]);
+    assert.equal(collection.length, 2);
+    assert.equal(collection.last().id, 1);
+  });
+
+  QUnit.test('#964 - collection.get return inconsistent', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection();
+    assert.ok(collection.get(null) === undefined);
+    assert.ok(collection.get() === undefined);
+  });
+
+  QUnit.test('#1112 - passing options.model sets collection.model', function(assert) {
+    assert.expect(2);
+    var Model = Backbone.Model.extend({});
+    var collection = new Backbone.Collection([{id: 1}], {model: Model});
+    assert.ok(collection.model === Model);
+    assert.ok(collection.at(0) instanceof Model);
+  });
+
+  QUnit.test('null and undefined are invalid ids.', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model({id: 1});
+    var collection = new Backbone.Collection([model]);
+    model.set({id: null});
+    assert.ok(!collection.get('null'));
+    model.set({id: 1});
+    model.set({id: undefined});
+    assert.ok(!collection.get('undefined'));
+  });
+
+  QUnit.test('falsy comparator', function(assert) {
+    assert.expect(4);
+    var Col = Backbone.Collection.extend({
+      comparator: function(model){ return model.id; }
+    });
+    var collection = new Col();
+    var colFalse = new Col(null, {comparator: false});
+    var colNull = new Col(null, {comparator: null});
+    var colUndefined = new Col(null, {comparator: undefined});
+    assert.ok(collection.comparator);
+    assert.ok(!colFalse.comparator);
+    assert.ok(!colNull.comparator);
+    assert.ok(colUndefined.comparator);
+  });
+
+  QUnit.test('#1355 - `options` is passed to success callbacks', function(assert) {
+    assert.expect(2);
+    var m = new Backbone.Model({x: 1});
+    var collection = new Backbone.Collection();
+    var opts = {
+      opts: true,
+      success: function(coll, resp, options) {
+        assert.ok(options.opts);
+      }
+    };
+    collection.sync = m.sync = function( method, coll, options ){
+      options.success({});
+    };
+    collection.fetch(opts);
+    collection.create(m, opts);
+  });
+
+  QUnit.test("#1412 - Trigger 'request' and 'sync' events.", function(assert) {
+    assert.expect(4);
+    var collection = new Backbone.Collection;
+    collection.url = '/test';
+    Backbone.ajax = function(settings){ settings.success(); };
+
+    collection.on('request', function(obj, xhr, options) {
+      assert.ok(obj === collection, "collection has correct 'request' event after fetching");
+    });
+    collection.on('sync', function(obj, response, options) {
+      assert.ok(obj === collection, "collection has correct 'sync' event after fetching");
+    });
+    collection.fetch();
+    collection.off();
+
+    collection.on('request', function(obj, xhr, options) {
+      assert.ok(obj === collection.get(1), "collection has correct 'request' event after one of its models save");
+    });
+    collection.on('sync', function(obj, response, options) {
+      assert.ok(obj === collection.get(1), "collection has correct 'sync' event after one of its models save");
+    });
+    collection.create({id: 1});
+    collection.off();
+  });
+
+  QUnit.test('#3283 - fetch, create calls success with context', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection;
+    collection.url = '/test';
+    Backbone.ajax = function(settings) {
+      settings.success.call(settings.context);
+    };
+    var obj = {};
+    var options = {
+      context: obj,
+      success: function() {
+        assert.equal(this, obj);
+      }
+    };
+
+    collection.fetch(options);
+    collection.create({id: 1}, options);
+  });
+
+  QUnit.test('#1447 - create with wait adds model.', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection;
+    var model = new Backbone.Model;
+    model.sync = function(method, m, options){ options.success(); };
+    collection.on('add', function(){ assert.ok(true); });
+    collection.create(model, {wait: true});
+  });
+
+  QUnit.test('#1448 - add sorts collection after merge.', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([
+      {id: 1, x: 1},
+      {id: 2, x: 2}
+    ]);
+    collection.comparator = function(model){ return model.get('x'); };
+    collection.add({id: 1, x: 3}, {merge: true});
+    assert.deepEqual(collection.pluck('id'), [2, 1]);
+  });
+
+  QUnit.test('#1655 - groupBy can be used with a string argument.', function(assert) {
+    assert.expect(3);
+    var collection = new Backbone.Collection([{x: 1}, {x: 2}]);
+    var grouped = collection.groupBy('x');
+    assert.strictEqual(_.keys(grouped).length, 2);
+    assert.strictEqual(grouped[1][0].get('x'), 1);
+    assert.strictEqual(grouped[2][0].get('x'), 2);
+  });
+
+  QUnit.test('#1655 - sortBy can be used with a string argument.', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{x: 3}, {x: 1}, {x: 2}]);
+    var values = _.map(collection.sortBy('x'), function(model) {
+      return model.get('x');
+    });
+    assert.deepEqual(values, [1, 2, 3]);
+  });
+
+  QUnit.test('#1604 - Removal during iteration.', function(assert) {
+    assert.expect(0);
+    var collection = new Backbone.Collection([{}, {}]);
+    collection.on('add', function() {
+      collection.at(0).destroy();
+    });
+    collection.add({}, {at: 0});
+  });
+
+  QUnit.test('#1638 - `sort` during `add` triggers correctly.', function(assert) {
+    var collection = new Backbone.Collection;
+    collection.comparator = function(model) { return model.get('x'); };
+    var added = [];
+    collection.on('add', function(model) {
+      model.set({x: 3});
+      collection.sort();
+      added.push(model.id);
+    });
+    collection.add([{id: 1, x: 1}, {id: 2, x: 2}]);
+    assert.deepEqual(added, [1, 2]);
+  });
+
+  QUnit.test('fetch parses models by default', function(assert) {
+    assert.expect(1);
+    var model = {};
+    var Collection = Backbone.Collection.extend({
+      url: 'test',
+      model: Backbone.Model.extend({
+        parse: function(resp) {
+          assert.strictEqual(resp, model);
+        }
+      })
+    });
+    new Collection().fetch();
+    this.ajaxSettings.success([model]);
+  });
+
+  QUnit.test("`sort` shouldn't always fire on `add`", function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}], {
+      comparator: 'id'
+    });
+    collection.sort = function(){ assert.ok(true); };
+    collection.add([]);
+    collection.add({id: 1});
+    collection.add([{id: 2}, {id: 3}]);
+    collection.add({id: 4});
+  });
+
+  QUnit.test('#1407 parse option on constructor parses collection and models', function(assert) {
+    assert.expect(2);
+    var model = {
+      namespace: [{id: 1}, {id: 2}]
+    };
+    var Collection = Backbone.Collection.extend({
+      model: Backbone.Model.extend({
+        parse: function(m) {
+          m.name = 'test';
+          return m;
+        }
+      }),
+      parse: function(m) {
+        return m.namespace;
+      }
+    });
+    var collection = new Collection(model, {parse: true});
+
+    assert.equal(collection.length, 2);
+    assert.equal(collection.at(0).get('name'), 'test');
+  });
+
+  QUnit.test('#1407 parse option on reset parses collection and models', function(assert) {
+    assert.expect(2);
+    var model = {
+      namespace: [{id: 1}, {id: 2}]
+    };
+    var Collection = Backbone.Collection.extend({
+      model: Backbone.Model.extend({
+        parse: function(m) {
+          m.name = 'test';
+          return m;
+        }
+      }),
+      parse: function(m) {
+        return m.namespace;
+      }
+    });
+    var collection = new Collection();
+    collection.reset(model, {parse: true});
+
+    assert.equal(collection.length, 2);
+    assert.equal(collection.at(0).get('name'), 'test');
+  });
+
+
+  QUnit.test('Reset includes previous models in triggered event.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    var collection = new Backbone.Collection([model]);
+    collection.on('reset', function(coll, options) {
+      assert.deepEqual(options.previousModels, [model]);
+    });
+    collection.reset([]);
+  });
+
+  QUnit.test('set', function(assert) {
+    var m1 = new Backbone.Model();
+    var m2 = new Backbone.Model({id: 2});
+    var m3 = new Backbone.Model();
+    var collection = new Backbone.Collection([m1, m2]);
+
+    // Test add/change/remove events
+    collection.on('add', function(model) {
+      assert.strictEqual(model, m3);
+    });
+    collection.on('change', function(model) {
+      assert.strictEqual(model, m2);
+    });
+    collection.on('remove', function(model) {
+      assert.strictEqual(model, m1);
+    });
+
+    // remove: false doesn't remove any models
+    collection.set([], {remove: false});
+    assert.strictEqual(collection.length, 2);
+
+    // add: false doesn't add any models
+    collection.set([m1, m2, m3], {add: false});
+    assert.strictEqual(collection.length, 2);
+
+    // merge: false doesn't change any models
+    collection.set([m1, {id: 2, a: 1}], {merge: false});
+    assert.strictEqual(m2.get('a'), void 0);
+
+    // add: false, remove: false only merges existing models
+    collection.set([m1, {id: 2, a: 0}, m3, {id: 4}], {add: false, remove: false});
+    assert.strictEqual(collection.length, 2);
+    assert.strictEqual(m2.get('a'), 0);
+
+    // default options add/remove/merge as appropriate
+    collection.set([{id: 2, a: 1}, m3]);
+    assert.strictEqual(collection.length, 2);
+    assert.strictEqual(m2.get('a'), 1);
+
+    // Test removing models not passing an argument
+    collection.off('remove').on('remove', function(model) {
+      assert.ok(model === m2 || model === m3);
+    });
+    collection.set([]);
+    assert.strictEqual(collection.length, 0);
+
+    // Test null models on set doesn't clear collection
+    collection.off();
+    collection.set([{id: 1}]);
+    collection.set();
+    assert.strictEqual(collection.length, 1);
+  });
+
+  QUnit.test('set with only cids', function(assert) {
+    assert.expect(3);
+    var m1 = new Backbone.Model;
+    var m2 = new Backbone.Model;
+    var collection = new Backbone.Collection;
+    collection.set([m1, m2]);
+    assert.equal(collection.length, 2);
+    collection.set([m1]);
+    assert.equal(collection.length, 1);
+    collection.set([m1, m1, m1, m2, m2], {remove: false});
+    assert.equal(collection.length, 2);
+  });
+
+  QUnit.test('set with only idAttribute', function(assert) {
+    assert.expect(3);
+    var m1 = {_id: 1};
+    var m2 = {_id: 2};
+    var Col = Backbone.Collection.extend({
+      model: Backbone.Model.extend({
+        idAttribute: '_id'
+      })
+    });
+    var collection = new Col;
+    collection.set([m1, m2]);
+    assert.equal(collection.length, 2);
+    collection.set([m1]);
+    assert.equal(collection.length, 1);
+    collection.set([m1, m1, m1, m2, m2], {remove: false});
+    assert.equal(collection.length, 2);
+  });
+
+  QUnit.test('set + merge with default values defined', function(assert) {
+    var Model = Backbone.Model.extend({
+      defaults: {
+        key: 'value'
+      }
+    });
+    var m = new Model({id: 1});
+    var collection = new Backbone.Collection([m], {model: Model});
+    assert.equal(collection.first().get('key'), 'value');
+
+    collection.set({id: 1, key: 'other'});
+    assert.equal(collection.first().get('key'), 'other');
+
+    collection.set({id: 1, other: 'value'});
+    assert.equal(collection.first().get('key'), 'other');
+    assert.equal(collection.length, 1);
+  });
+
+  QUnit.test('merge without mutation', function(assert) {
+    var Model = Backbone.Model.extend({
+      initialize: function(attrs, options) {
+        if (attrs.child) {
+          this.set('child', new Model(attrs.child, options), options);
+        }
+      }
+    });
+    var Collection = Backbone.Collection.extend({model: Model});
+    var data = [{id: 1, child: {id: 2}}];
+    var collection = new Collection(data);
+    assert.equal(collection.first().id, 1);
+    collection.set(data);
+    assert.equal(collection.first().id, 1);
+    collection.set([{id: 2, child: {id: 2}}].concat(data));
+    assert.deepEqual(collection.pluck('id'), [2, 1]);
+  });
+
+  QUnit.test('`set` and model level `parse`', function(assert) {
+    var Model = Backbone.Model.extend({});
+    var Collection = Backbone.Collection.extend({
+      model: Model,
+      parse: function(res) { return _.map(res.models, 'model'); }
+    });
+    var model = new Model({id: 1});
+    var collection = new Collection(model);
+    collection.set({models: [
+      {model: {id: 1}},
+      {model: {id: 2}}
+    ]}, {parse: true});
+    assert.equal(collection.first(), model);
+  });
+
+  QUnit.test('`set` data is only parsed once', function(assert) {
+    var collection = new Backbone.Collection();
+    collection.model = Backbone.Model.extend({
+      parse: function(data) {
+        assert.equal(data.parsed, void 0);
+        data.parsed = true;
+        return data;
+      }
+    });
+    collection.set({}, {parse: true});
+  });
+
+  QUnit.test('`set` matches input order in the absence of a comparator', function(assert) {
+    var one = new Backbone.Model({id: 1});
+    var two = new Backbone.Model({id: 2});
+    var three = new Backbone.Model({id: 3});
+    var collection = new Backbone.Collection([one, two, three]);
+    collection.set([{id: 3}, {id: 2}, {id: 1}]);
+    assert.deepEqual(collection.models, [three, two, one]);
+    collection.set([{id: 1}, {id: 2}]);
+    assert.deepEqual(collection.models, [one, two]);
+    collection.set([two, three, one]);
+    assert.deepEqual(collection.models, [two, three, one]);
+    collection.set([{id: 1}, {id: 2}], {remove: false});
+    assert.deepEqual(collection.models, [two, three, one]);
+    collection.set([{id: 1}, {id: 2}, {id: 3}], {merge: false});
+    assert.deepEqual(collection.models, [one, two, three]);
+    collection.set([three, two, one, {id: 4}], {add: false});
+    assert.deepEqual(collection.models, [one, two, three]);
+  });
+
+  QUnit.test('#1894 - Push should not trigger a sort', function(assert) {
+    assert.expect(0);
+    var Collection = Backbone.Collection.extend({
+      comparator: 'id',
+      sort: function() { assert.ok(false); }
+    });
+    new Collection().push({id: 1});
+  });
+
+  QUnit.test('#2428 - push duplicate models, return the correct one', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection;
+    var model1 = collection.push({id: 101});
+    var model2 = collection.push({id: 101});
+    assert.ok(model2.cid === model1.cid);
+  });
+
+  QUnit.test('`set` with non-normal id', function(assert) {
+    var Collection = Backbone.Collection.extend({
+      model: Backbone.Model.extend({idAttribute: '_id'})
+    });
+    var collection = new Collection({_id: 1});
+    collection.set([{_id: 1, a: 1}], {add: false});
+    assert.equal(collection.first().get('a'), 1);
+  });
+
+  QUnit.test('#1894 - `sort` can optionally be turned off', function(assert) {
+    assert.expect(0);
+    var Collection = Backbone.Collection.extend({
+      comparator: 'id',
+      sort: function() { assert.ok(false); }
+    });
+    new Collection().add({id: 1}, {sort: false});
+  });
+
+  QUnit.test('#1915 - `parse` data in the right order in `set`', function(assert) {
+    var collection = new (Backbone.Collection.extend({
+      parse: function(data) {
+        assert.strictEqual(data.status, 'ok');
+        return data.data;
+      }
+    }));
+    var res = {status: 'ok', data: [{id: 1}]};
+    collection.set(res, {parse: true});
+  });
+
+  QUnit.test('#1939 - `parse` is passed `options`', function(assert) {
+    var done = assert.async();
+    assert.expect(1);
+    var collection = new (Backbone.Collection.extend({
+      url: '/',
+      parse: function(data, options) {
+        assert.strictEqual(options.xhr.someHeader, 'headerValue');
+        return data;
+      }
+    }));
+    var ajax = Backbone.ajax;
+    Backbone.ajax = function(params) {
+      _.defer(params.success, []);
+      return {someHeader: 'headerValue'};
+    };
+    collection.fetch({
+      success: function() { done(); }
+    });
+    Backbone.ajax = ajax;
+  });
+
+  QUnit.test('fetch will pass extra options to success callback', function(assert) {
+    assert.expect(1);
+    var SpecialSyncCollection = Backbone.Collection.extend({
+      url: '/test',
+      sync: function(method, collection, options) {
+        _.extend(options, {specialSync: true});
+        return Backbone.Collection.prototype.sync.call(this, method, collection, options);
+      }
+    });
+
+    var collection = new SpecialSyncCollection();
+
+    var onSuccess = function(coll, resp, options) {
+      assert.ok(options.specialSync, 'Options were passed correctly to callback');
+    };
+
+    collection.fetch({success: onSuccess});
+    this.ajaxSettings.success();
+  });
+
+  QUnit.test('`add` only `sort`s when necessary', function(assert) {
+    assert.expect(2);
+    var collection = new (Backbone.Collection.extend({
+      comparator: 'a'
+    }))([{id: 1}, {id: 2}, {id: 3}]);
+    collection.on('sort', function() { assert.ok(true); });
+    collection.add({id: 4}); // do sort, new model
+    collection.add({id: 1, a: 1}, {merge: true}); // do sort, comparator change
+    collection.add({id: 1, b: 1}, {merge: true}); // don't sort, no comparator change
+    collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no comparator change
+    collection.add(collection.models); // don't sort, nothing new
+    collection.add(collection.models, {merge: true}); // don't sort
+  });
+
+  QUnit.test('`add` only `sort`s when necessary with comparator function', function(assert) {
+    assert.expect(3);
+    var collection = new (Backbone.Collection.extend({
+      comparator: function(m1, m2) {
+        return m1.get('a') > m2.get('a') ? 1 : (m1.get('a') < m2.get('a') ? -1 : 0);
+      }
+    }))([{id: 1}, {id: 2}, {id: 3}]);
+    collection.on('sort', function() { assert.ok(true); });
+    collection.add({id: 4}); // do sort, new model
+    collection.add({id: 1, a: 1}, {merge: true}); // do sort, model change
+    collection.add({id: 1, b: 1}, {merge: true}); // do sort, model change
+    collection.add({id: 1, a: 1}, {merge: true}); // don't sort, no model change
+    collection.add(collection.models); // don't sort, nothing new
+    collection.add(collection.models, {merge: true}); // don't sort
+  });
+
+  QUnit.test('Attach options to collection.', function(assert) {
+    assert.expect(2);
+    var Model = Backbone.Model;
+    var comparator = function(){};
+
+    var collection = new Backbone.Collection([], {
+      model: Model,
+      comparator: comparator
+    });
+
+    assert.ok(collection.model === Model);
+    assert.ok(collection.comparator === comparator);
+  });
+
+  QUnit.test('Pass falsey for `models` for empty Col with `options`', function(assert) {
+    assert.expect(9);
+    var opts = {a: 1, b: 2};
+    _.forEach([undefined, null, false], function(falsey) {
+      var Collection = Backbone.Collection.extend({
+        initialize: function(models, options) {
+          assert.strictEqual(models, falsey);
+          assert.strictEqual(options, opts);
+        }
+      });
+
+      var collection = new Collection(falsey, opts);
+      assert.strictEqual(collection.length, 0);
+    });
+  });
+
+  QUnit.test('`add` overrides `set` flags', function(assert) {
+    var collection = new Backbone.Collection();
+    collection.once('add', function(model, coll, options) {
+      coll.add({id: 2}, options);
+    });
+    collection.set({id: 1});
+    assert.equal(collection.length, 2);
+  });
+
+  QUnit.test('#2606 - Collection#create, success arguments', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection;
+    collection.url = 'test';
+    collection.create({}, {
+      success: function(model, resp, options) {
+        assert.strictEqual(resp, 'response');
+      }
+    });
+    this.ajaxSettings.success('response');
+  });
+
+  QUnit.test('#2612 - nested `parse` works with `Collection#set`', function(assert) {
+
+    var Job = Backbone.Model.extend({
+      constructor: function() {
+        this.items = new Items();
+        Backbone.Model.apply(this, arguments);
+      },
+      parse: function(attrs) {
+        this.items.set(attrs.items, {parse: true});
+        return _.omit(attrs, 'items');
+      }
+    });
+
+    var Item = Backbone.Model.extend({
+      constructor: function() {
+        this.subItems = new Backbone.Collection();
+        Backbone.Model.apply(this, arguments);
+      },
+      parse: function(attrs) {
+        this.subItems.set(attrs.subItems, {parse: true});
+        return _.omit(attrs, 'subItems');
+      }
+    });
+
+    var Items = Backbone.Collection.extend({
+      model: Item
+    });
+
+    var data = {
+      name: 'JobName',
+      id: 1,
+      items: [{
+        id: 1,
+        name: 'Sub1',
+        subItems: [
+          {id: 1, subName: 'One'},
+          {id: 2, subName: 'Two'}
+        ]
+      }, {
+        id: 2,
+        name: 'Sub2',
+        subItems: [
+          {id: 3, subName: 'Three'},
+          {id: 4, subName: 'Four'}
+        ]
+      }]
+    };
+
+    var newData = {
+      name: 'NewJobName',
+      id: 1,
+      items: [{
+        id: 1,
+        name: 'NewSub1',
+        subItems: [
+          {id: 1, subName: 'NewOne'},
+          {id: 2, subName: 'NewTwo'}
+        ]
+      }, {
+        id: 2,
+        name: 'NewSub2',
+        subItems: [
+          {id: 3, subName: 'NewThree'},
+          {id: 4, subName: 'NewFour'}
+        ]
+      }]
+    };
+
+    var job = new Job(data, {parse: true});
+    assert.equal(job.get('name'), 'JobName');
+    assert.equal(job.items.at(0).get('name'), 'Sub1');
+    assert.equal(job.items.length, 2);
+    assert.equal(job.items.get(1).subItems.get(1).get('subName'), 'One');
+    assert.equal(job.items.get(2).subItems.get(3).get('subName'), 'Three');
+    job.set(job.parse(newData, {parse: true}));
+    assert.equal(job.get('name'), 'NewJobName');
+    assert.equal(job.items.at(0).get('name'), 'NewSub1');
+    assert.equal(job.items.length, 2);
+    assert.equal(job.items.get(1).subItems.get(1).get('subName'), 'NewOne');
+    assert.equal(job.items.get(2).subItems.get(3).get('subName'), 'NewThree');
+  });
+
+  QUnit.test('_addReference binds all collection events & adds to the lookup hashes', function(assert) {
+    assert.expect(8);
+
+    var calls = {add: 0, remove: 0};
+
+    var Collection = Backbone.Collection.extend({
+
+      _addReference: function(model) {
+        Backbone.Collection.prototype._addReference.apply(this, arguments);
+        calls.add++;
+        assert.equal(model, this._byId[model.id]);
+        assert.equal(model, this._byId[model.cid]);
+        assert.equal(model._events.all.length, 1);
+      },
+
+      _removeReference: function(model) {
+        Backbone.Collection.prototype._removeReference.apply(this, arguments);
+        calls.remove++;
+        assert.equal(this._byId[model.id], void 0);
+        assert.equal(this._byId[model.cid], void 0);
+        assert.equal(model.collection, void 0);
+      }
+
+    });
+
+    var collection = new Collection();
+    var model = collection.add({id: 1});
+    collection.remove(model);
+
+    assert.equal(calls.add, 1);
+    assert.equal(calls.remove, 1);
+  });
+
+  QUnit.test('Do not allow duplicate models to be `add`ed or `set`', function(assert) {
+    var collection = new Backbone.Collection();
+
+    collection.add([{id: 1}, {id: 1}]);
+    assert.equal(collection.length, 1);
+    assert.equal(collection.models.length, 1);
+
+    collection.set([{id: 1}, {id: 1}]);
+    assert.equal(collection.length, 1);
+    assert.equal(collection.models.length, 1);
+  });
+
+  QUnit.test('#3020: #set with {add: false} should not throw.', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection;
+    collection.set([{id: 1}], {add: false});
+    assert.strictEqual(collection.length, 0);
+    assert.strictEqual(collection.models.length, 0);
+  });
+
+  QUnit.test('create with wait, model instance, #3028', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection();
+    var model = new Backbone.Model({id: 1});
+    model.sync = function(){
+      assert.equal(this.collection, collection);
+    };
+    collection.create(model, {wait: true});
+  });
+
+  QUnit.test('modelId', function(assert) {
+    var Stooge = Backbone.Model.extend();
+    var StoogeCollection = Backbone.Collection.extend({model: Stooge});
+
+    // Default to using `Collection::model::idAttribute`.
+    assert.equal(StoogeCollection.prototype.modelId({id: 1}), 1);
+    Stooge.prototype.idAttribute = '_id';
+    assert.equal(StoogeCollection.prototype.modelId({_id: 1}), 1);
+  });
+
+  QUnit.test('Polymorphic models work with "simple" constructors', function(assert) {
+    var A = Backbone.Model.extend();
+    var B = Backbone.Model.extend();
+    var C = Backbone.Collection.extend({
+      model: function(attrs) {
+        return attrs.type === 'a' ? new A(attrs) : new B(attrs);
+      }
+    });
+    var collection = new C([{id: 1, type: 'a'}, {id: 2, type: 'b'}]);
+    assert.equal(collection.length, 2);
+    assert.ok(collection.at(0) instanceof A);
+    assert.equal(collection.at(0).id, 1);
+    assert.ok(collection.at(1) instanceof B);
+    assert.equal(collection.at(1).id, 2);
+  });
+
+  QUnit.test('Polymorphic models work with "advanced" constructors', function(assert) {
+    var A = Backbone.Model.extend({idAttribute: '_id'});
+    var B = Backbone.Model.extend({idAttribute: '_id'});
+    var C = Backbone.Collection.extend({
+      model: Backbone.Model.extend({
+        constructor: function(attrs) {
+          return attrs.type === 'a' ? new A(attrs) : new B(attrs);
+        },
+
+        idAttribute: '_id'
+      })
+    });
+    var collection = new C([{_id: 1, type: 'a'}, {_id: 2, type: 'b'}]);
+    assert.equal(collection.length, 2);
+    assert.ok(collection.at(0) instanceof A);
+    assert.equal(collection.at(0), collection.get(1));
+    assert.ok(collection.at(1) instanceof B);
+    assert.equal(collection.at(1), collection.get(2));
+
+    C = Backbone.Collection.extend({
+      model: function(attrs) {
+        return attrs.type === 'a' ? new A(attrs) : new B(attrs);
+      },
+
+      modelId: function(attrs) {
+        return attrs.type + '-' + attrs.id;
+      }
+    });
+    collection = new C([{id: 1, type: 'a'}, {id: 1, type: 'b'}]);
+    assert.equal(collection.length, 2);
+    assert.ok(collection.at(0) instanceof A);
+    assert.equal(collection.at(0), collection.get('a-1'));
+    assert.ok(collection.at(1) instanceof B);
+    assert.equal(collection.at(1), collection.get('b-1'));
+  });
+
+  QUnit.test('Collection with polymorphic models receives default id from modelId', function(assert) {
+    assert.expect(6);
+    // When the polymorphic models use 'id' for the idAttribute, all is fine.
+    var C1 = Backbone.Collection.extend({
+      model: function(attrs) {
+        return new Backbone.Model(attrs);
+      }
+    });
+    var c1 = new C1({id: 1});
+    assert.equal(c1.get(1).id, 1);
+    assert.equal(c1.modelId({id: 1}), 1);
+
+    // If the polymorphic models define their own idAttribute,
+    // the modelId method should be overridden, for the reason below.
+    var M = Backbone.Model.extend({
+      idAttribute: '_id'
+    });
+    var C2 = Backbone.Collection.extend({
+      model: function(attrs) {
+        return new M(attrs);
+      }
+    });
+    var c2 = new C2({'_id': 1});
+    assert.equal(c2.get(1), void 0);
+    assert.equal(c2.modelId(c2.at(0).attributes), void 0);
+    var m = new M({'_id': 2});
+    c2.add(m);
+    assert.equal(c2.get(2), void 0);
+    assert.equal(c2.modelId(m.attributes), void 0);
+  });
+
+  QUnit.test('#3039 #3951: adding at index fires with correct at', function(assert) {
+    assert.expect(4);
+    var collection = new Backbone.Collection([{val: 0}, {val: 4}]);
+    collection.on('add', function(model, coll, options) {
+      assert.equal(model.get('val'), options.index);
+    });
+    collection.add([{val: 1}, {val: 2}, {val: 3}], {at: 1});
+    collection.add({val: 5}, {at: 10});
+  });
+
+  QUnit.test('#3039: index is not sent when at is not specified', function(assert) {
+    assert.expect(2);
+    var collection = new Backbone.Collection([{at: 0}]);
+    collection.on('add', function(model, coll, options) {
+      assert.equal(undefined, options.index);
+    });
+    collection.add([{at: 1}, {at: 2}]);
+  });
+
+  QUnit.test('#3199 - Order changing should trigger a sort', function(assert) {
+    assert.expect(1);
+    var one = new Backbone.Model({id: 1});
+    var two = new Backbone.Model({id: 2});
+    var three = new Backbone.Model({id: 3});
+    var collection = new Backbone.Collection([one, two, three]);
+    collection.on('sort', function() {
+      assert.ok(true);
+    });
+    collection.set([{id: 3}, {id: 2}, {id: 1}]);
+  });
+
+  QUnit.test('#3199 - Adding a model should trigger a sort', function(assert) {
+    assert.expect(1);
+    var one = new Backbone.Model({id: 1});
+    var two = new Backbone.Model({id: 2});
+    var three = new Backbone.Model({id: 3});
+    var collection = new Backbone.Collection([one, two, three]);
+    collection.on('sort', function() {
+      assert.ok(true);
+    });
+    collection.set([{id: 1}, {id: 2}, {id: 3}, {id: 0}]);
+  });
+
+  QUnit.test('#3199 - Order not changing should not trigger a sort', function(assert) {
+    assert.expect(0);
+    var one = new Backbone.Model({id: 1});
+    var two = new Backbone.Model({id: 2});
+    var three = new Backbone.Model({id: 3});
+    var collection = new Backbone.Collection([one, two, three]);
+    collection.on('sort', function() {
+      assert.ok(false);
+    });
+    collection.set([{id: 1}, {id: 2}, {id: 3}]);
+  });
+
+  QUnit.test('add supports negative indexes', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 1}]);
+    collection.add([{id: 2}, {id: 3}], {at: -1});
+    collection.add([{id: 2.5}], {at: -2});
+    collection.add([{id: 0.5}], {at: -6});
+    assert.equal(collection.pluck('id').join(','), '0.5,1,2,2.5,3');
+  });
+
+  QUnit.test('#set accepts options.at as a string', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
+    collection.add([{id: 3}], {at: '1'});
+    assert.deepEqual(collection.pluck('id'), [1, 3, 2]);
+  });
+
+  QUnit.test('adding multiple models triggers `update` event once', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection;
+    collection.on('update', function() { assert.ok(true); });
+    collection.add([{id: 1}, {id: 2}, {id: 3}]);
+  });
+
+  QUnit.test('removing models triggers `update` event once', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}, {id: 3}]);
+    collection.on('update', function() { assert.ok(true); });
+    collection.remove([{id: 1}, {id: 2}]);
+  });
+
+  QUnit.test('remove does not trigger `update` when nothing removed', function(assert) {
+    assert.expect(0);
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
+    collection.on('update', function() { assert.ok(false); });
+    collection.remove([{id: 3}]);
+  });
+
+  QUnit.test('set triggers `set` event once', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
+    collection.on('update', function() { assert.ok(true); });
+    collection.set([{id: 1}, {id: 3}]);
+  });
+
+  QUnit.test('set does not trigger `update` event when nothing added nor removed', function(assert) {
+    var collection = new Backbone.Collection([{id: 1}, {id: 2}]);
+    collection.on('update', function(coll, options) {
+      assert.equal(options.changes.added.length, 0);
+      assert.equal(options.changes.removed.length, 0);
+      assert.equal(options.changes.merged.length, 2);
+    });
+    collection.set([{id: 1}, {id: 2}]);
+  });
+
+  QUnit.test('#3610 - invoke collects arguments', function(assert) {
+    assert.expect(3);
+    var Model = Backbone.Model.extend({
+      method: function(x, y, z) {
+        assert.equal(x, 1);
+        assert.equal(y, 2);
+        assert.equal(z, 3);
+      }
+    });
+    var Collection = Backbone.Collection.extend({
+      model: Model
+    });
+    var collection = new Collection([{id: 1}]);
+    collection.invoke('method', 1, 2, 3);
+  });
+
+  QUnit.test('#3662 - triggering change without model will not error', function(assert) {
+    assert.expect(1);
+    var collection = new Backbone.Collection([{id: 1}]);
+    var model = collection.first();
+    collection.on('change', function(m) {
+      assert.equal(m, undefined);
+    });
+    model.trigger('change');
+  });
+
+  QUnit.test('#3871 - falsy parse result creates empty collection', function(assert) {
+    var collection = new (Backbone.Collection.extend({
+      parse: function(data, options) {}
+    }));
+    collection.set('', {parse: true});
+    assert.equal(collection.length, 0);
+  });
+
+  QUnit.test("#3711 - remove's `update` event returns one removed model", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var collection = new Backbone.Collection([model]);
+    collection.on('update', function(context, options) {
+      var changed = options.changes;
+      assert.deepEqual(changed.added, []);
+      assert.deepEqual(changed.merged, []);
+      assert.strictEqual(changed.removed[0], model);
+    });
+    collection.remove(model);
+  });
+
+  QUnit.test("#3711 - remove's `update` event returns multiple removed models", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
+    var collection = new Backbone.Collection([model, model2]);
+    collection.on('update', function(context, options) {
+      var changed = options.changes;
+      assert.deepEqual(changed.added, []);
+      assert.deepEqual(changed.merged, []);
+      assert.ok(changed.removed.length === 2);
+
+      assert.ok(_.indexOf(changed.removed, model) > -1 && _.indexOf(changed.removed, model2) > -1);
+    });
+    collection.remove([model, model2]);
+  });
+
+  QUnit.test("#3711 - set's `update` event returns one added model", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var collection = new Backbone.Collection();
+    collection.on('update', function(context, options) {
+      var addedModels = options.changes.added;
+      assert.ok(addedModels.length === 1);
+      assert.strictEqual(addedModels[0], model);
+    });
+    collection.set(model);
+  });
+
+  QUnit.test("#3711 - set's `update` event returns multiple added models", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
+    var collection = new Backbone.Collection();
+    collection.on('update', function(context, options) {
+      var addedModels = options.changes.added;
+      assert.ok(addedModels.length === 2);
+      assert.strictEqual(addedModels[0], model);
+      assert.strictEqual(addedModels[1], model2);
+    });
+    collection.set([model, model2]);
+  });
+
+  QUnit.test("#3711 - set's `update` event returns one removed model", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
+    var model3 = new Backbone.Model({id: 3, title: 'My Last Post'});
+    var collection = new Backbone.Collection([model]);
+    collection.on('update', function(context, options) {
+      var changed = options.changes;
+      assert.equal(changed.added.length, 2);
+      assert.equal(changed.merged.length, 0);
+      assert.ok(changed.removed.length === 1);
+      assert.strictEqual(changed.removed[0], model);
+    });
+    collection.set([model2, model3]);
+  });
+
+  QUnit.test("#3711 - set's `update` event returns multiple removed models", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
+    var model3 = new Backbone.Model({id: 3, title: 'My Last Post'});
+    var collection = new Backbone.Collection([model, model2]);
+    collection.on('update', function(context, options) {
+      var removedModels = options.changes.removed;
+      assert.ok(removedModels.length === 2);
+      assert.strictEqual(removedModels[0], model);
+      assert.strictEqual(removedModels[1], model2);
+    });
+    collection.set([model3]);
+  });
+
+  QUnit.test("#3711 - set's `update` event returns one merged model", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
+    var model2Update = new Backbone.Model({id: 2, title: 'Second Post V2'});
+    var collection = new Backbone.Collection([model, model2]);
+    collection.on('update', function(context, options) {
+      var mergedModels = options.changes.merged;
+      assert.ok(mergedModels.length === 1);
+      assert.strictEqual(mergedModels[0].get('title'), model2Update.get('title'));
+    });
+    collection.set([model2Update]);
+  });
+
+  QUnit.test("#3711 - set's `update` event returns multiple merged models", function(assert) {
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var modelUpdate = new Backbone.Model({id: 1, title: 'First Post V2'});
+    var model2 = new Backbone.Model({id: 2, title: 'Second Post'});
+    var model2Update = new Backbone.Model({id: 2, title: 'Second Post V2'});
+    var collection = new Backbone.Collection([model, model2]);
+    collection.on('update', function(context, options) {
+      var mergedModels = options.changes.merged;
+      assert.ok(mergedModels.length === 2);
+      assert.strictEqual(mergedModels[0].get('title'), model2Update.get('title'));
+      assert.strictEqual(mergedModels[1].get('title'), modelUpdate.get('title'));
+    });
+    collection.set([model2Update, modelUpdate]);
+  });
+
+  QUnit.test("#3711 - set's `update` event should not be triggered adding a model which already exists exactly alike", function(assert) {
+    var fired = false;
+    var model = new Backbone.Model({id: 1, title: 'First Post'});
+    var collection = new Backbone.Collection([model]);
+    collection.on('update', function(context, options) {
+      fired = true;
+    });
+    collection.set([model]);
+    assert.equal(fired, false);
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/events.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/events.js
new file mode 100644
index 0000000..544b39a
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/events.js
@@ -0,0 +1,706 @@
+(function() {
+
+  QUnit.module('Backbone.Events');
+
+  QUnit.test('on and trigger', function(assert) {
+    assert.expect(2);
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+    obj.on('event', function() { obj.counter += 1; });
+    obj.trigger('event');
+    assert.equal(obj.counter, 1, 'counter should be incremented.');
+    obj.trigger('event');
+    obj.trigger('event');
+    obj.trigger('event');
+    obj.trigger('event');
+    assert.equal(obj.counter, 5, 'counter should be incremented five times.');
+  });
+
+  QUnit.test('binding and triggering multiple events', function(assert) {
+    assert.expect(4);
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+
+    obj.on('a b c', function() { obj.counter += 1; });
+
+    obj.trigger('a');
+    assert.equal(obj.counter, 1);
+
+    obj.trigger('a b');
+    assert.equal(obj.counter, 3);
+
+    obj.trigger('c');
+    assert.equal(obj.counter, 4);
+
+    obj.off('a c');
+    obj.trigger('a b c');
+    assert.equal(obj.counter, 5);
+  });
+
+  QUnit.test('binding and triggering with event maps', function(assert) {
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+
+    var increment = function() {
+      this.counter += 1;
+    };
+
+    obj.on({
+      a: increment,
+      b: increment,
+      c: increment
+    }, obj);
+
+    obj.trigger('a');
+    assert.equal(obj.counter, 1);
+
+    obj.trigger('a b');
+    assert.equal(obj.counter, 3);
+
+    obj.trigger('c');
+    assert.equal(obj.counter, 4);
+
+    obj.off({
+      a: increment,
+      c: increment
+    }, obj);
+    obj.trigger('a b c');
+    assert.equal(obj.counter, 5);
+  });
+
+  QUnit.test('binding and triggering multiple event names with event maps', function(assert) {
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+
+    var increment = function() {
+      this.counter += 1;
+    };
+
+    obj.on({
+      'a b c': increment
+    });
+
+    obj.trigger('a');
+    assert.equal(obj.counter, 1);
+
+    obj.trigger('a b');
+    assert.equal(obj.counter, 3);
+
+    obj.trigger('c');
+    assert.equal(obj.counter, 4);
+
+    obj.off({
+      'a c': increment
+    });
+    obj.trigger('a b c');
+    assert.equal(obj.counter, 5);
+  });
+
+  QUnit.test('binding and trigger with event maps context', function(assert) {
+    assert.expect(2);
+    var obj = {counter: 0};
+    var context = {};
+    _.extend(obj, Backbone.Events);
+
+    obj.on({
+      a: function() {
+        assert.strictEqual(this, context, 'defaults `context` to `callback` param');
+      }
+    }, context).trigger('a');
+
+    obj.off().on({
+      a: function() {
+        assert.strictEqual(this, context, 'will not override explicit `context` param');
+      }
+    }, this, context).trigger('a');
+  });
+
+  QUnit.test('listenTo and stopListening', function(assert) {
+    assert.expect(1);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenTo(b, 'all', function(){ assert.ok(true); });
+    b.trigger('anything');
+    a.listenTo(b, 'all', function(){ assert.ok(false); });
+    a.stopListening();
+    b.trigger('anything');
+  });
+
+  QUnit.test('listenTo and stopListening with event maps', function(assert) {
+    assert.expect(4);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    var cb = function(){ assert.ok(true); };
+    a.listenTo(b, {event: cb});
+    b.trigger('event');
+    a.listenTo(b, {event2: cb});
+    b.on('event2', cb);
+    a.stopListening(b, {event2: cb});
+    b.trigger('event event2');
+    a.stopListening();
+    b.trigger('event event2');
+  });
+
+  QUnit.test('stopListening with omitted args', function(assert) {
+    assert.expect(2);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    var cb = function() { assert.ok(true); };
+    a.listenTo(b, 'event', cb);
+    b.on('event', cb);
+    a.listenTo(b, 'event2', cb);
+    a.stopListening(null, {event: cb});
+    b.trigger('event event2');
+    b.off();
+    a.listenTo(b, 'event event2', cb);
+    a.stopListening(null, 'event');
+    a.stopListening();
+    b.trigger('event2');
+  });
+
+  QUnit.test('listenToOnce', function(assert) {
+    assert.expect(2);
+    // Same as the previous test, but we use once rather than having to explicitly unbind
+    var obj = {counterA: 0, counterB: 0};
+    _.extend(obj, Backbone.Events);
+    var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
+    var incrB = function(){ obj.counterB += 1; };
+    obj.listenToOnce(obj, 'event', incrA);
+    obj.listenToOnce(obj, 'event', incrB);
+    obj.trigger('event');
+    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
+    assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
+  });
+
+  QUnit.test('listenToOnce and stopListening', function(assert) {
+    assert.expect(1);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenToOnce(b, 'all', function() { assert.ok(true); });
+    b.trigger('anything');
+    b.trigger('anything');
+    a.listenToOnce(b, 'all', function() { assert.ok(false); });
+    a.stopListening();
+    b.trigger('anything');
+  });
+
+  QUnit.test('listenTo, listenToOnce and stopListening', function(assert) {
+    assert.expect(1);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenToOnce(b, 'all', function() { assert.ok(true); });
+    b.trigger('anything');
+    b.trigger('anything');
+    a.listenTo(b, 'all', function() { assert.ok(false); });
+    a.stopListening();
+    b.trigger('anything');
+  });
+
+  QUnit.test('listenTo and stopListening with event maps', function(assert) {
+    assert.expect(1);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenTo(b, {change: function(){ assert.ok(true); }});
+    b.trigger('change');
+    a.listenTo(b, {change: function(){ assert.ok(false); }});
+    a.stopListening();
+    b.trigger('change');
+  });
+
+  QUnit.test('listenTo yourself', function(assert) {
+    assert.expect(1);
+    var e = _.extend({}, Backbone.Events);
+    e.listenTo(e, 'foo', function(){ assert.ok(true); });
+    e.trigger('foo');
+  });
+
+  QUnit.test('listenTo yourself cleans yourself up with stopListening', function(assert) {
+    assert.expect(1);
+    var e = _.extend({}, Backbone.Events);
+    e.listenTo(e, 'foo', function(){ assert.ok(true); });
+    e.trigger('foo');
+    e.stopListening();
+    e.trigger('foo');
+  });
+
+  QUnit.test('stopListening cleans up references', function(assert) {
+    assert.expect(12);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    var fn = function() {};
+    b.on('event', fn);
+    a.listenTo(b, 'event', fn).stopListening();
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenTo(b, 'event', fn).stopListening(b);
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenTo(b, 'event', fn).stopListening(b, 'event');
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenTo(b, 'event', fn).stopListening(b, 'event', fn);
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+  });
+
+  QUnit.test('stopListening cleans up references from listenToOnce', function(assert) {
+    assert.expect(12);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    var fn = function() {};
+    b.on('event', fn);
+    a.listenToOnce(b, 'event', fn).stopListening();
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenToOnce(b, 'event', fn).stopListening(b);
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenToOnce(b, 'event', fn).stopListening(b, 'event');
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenToOnce(b, 'event', fn).stopListening(b, 'event', fn);
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._events.event), 1);
+    assert.equal(_.size(b._listeners), 0);
+  });
+
+  QUnit.test('listenTo and off cleaning up references', function(assert) {
+    assert.expect(8);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    var fn = function() {};
+    a.listenTo(b, 'event', fn);
+    b.off();
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenTo(b, 'event', fn);
+    b.off('event');
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenTo(b, 'event', fn);
+    b.off(null, fn);
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._listeners), 0);
+    a.listenTo(b, 'event', fn);
+    b.off(null, null, a);
+    assert.equal(_.size(a._listeningTo), 0);
+    assert.equal(_.size(b._listeners), 0);
+  });
+
+  QUnit.test('listenTo and stopListening cleaning up references', function(assert) {
+    assert.expect(2);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenTo(b, 'all', function(){ assert.ok(true); });
+    b.trigger('anything');
+    a.listenTo(b, 'other', function(){ assert.ok(false); });
+    a.stopListening(b, 'other');
+    a.stopListening(b, 'all');
+    assert.equal(_.size(a._listeningTo), 0);
+  });
+
+  QUnit.test('listenToOnce without context cleans up references after the event has fired', function(assert) {
+    assert.expect(2);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenToOnce(b, 'all', function(){ assert.ok(true); });
+    b.trigger('anything');
+    assert.equal(_.size(a._listeningTo), 0);
+  });
+
+  QUnit.test('listenToOnce with event maps cleans up references', function(assert) {
+    assert.expect(2);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenToOnce(b, {
+      one: function() { assert.ok(true); },
+      two: function() { assert.ok(false); }
+    });
+    b.trigger('one');
+    assert.equal(_.size(a._listeningTo), 1);
+  });
+
+  QUnit.test('listenToOnce with event maps binds the correct `this`', function(assert) {
+    assert.expect(1);
+    var a = _.extend({}, Backbone.Events);
+    var b = _.extend({}, Backbone.Events);
+    a.listenToOnce(b, {
+      one: function() { assert.ok(this === a); },
+      two: function() { assert.ok(false); }
+    });
+    b.trigger('one');
+  });
+
+  QUnit.test("listenTo with empty callback doesn't throw an error", function(assert) {
+    assert.expect(1);
+    var e = _.extend({}, Backbone.Events);
+    e.listenTo(e, 'foo', null);
+    e.trigger('foo');
+    assert.ok(true);
+  });
+
+  QUnit.test('trigger all for each event', function(assert) {
+    assert.expect(3);
+    var a, b, obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+    obj.on('all', function(event) {
+      obj.counter++;
+      if (event === 'a') a = true;
+      if (event === 'b') b = true;
+    })
+    .trigger('a b');
+    assert.ok(a);
+    assert.ok(b);
+    assert.equal(obj.counter, 2);
+  });
+
+  QUnit.test('on, then unbind all functions', function(assert) {
+    assert.expect(1);
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+    var callback = function() { obj.counter += 1; };
+    obj.on('event', callback);
+    obj.trigger('event');
+    obj.off('event');
+    obj.trigger('event');
+    assert.equal(obj.counter, 1, 'counter should have only been incremented once.');
+  });
+
+  QUnit.test('bind two callbacks, unbind only one', function(assert) {
+    assert.expect(2);
+    var obj = {counterA: 0, counterB: 0};
+    _.extend(obj, Backbone.Events);
+    var callback = function() { obj.counterA += 1; };
+    obj.on('event', callback);
+    obj.on('event', function() { obj.counterB += 1; });
+    obj.trigger('event');
+    obj.off('event', callback);
+    obj.trigger('event');
+    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
+    assert.equal(obj.counterB, 2, 'counterB should have been incremented twice.');
+  });
+
+  QUnit.test('unbind a callback in the midst of it firing', function(assert) {
+    assert.expect(1);
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+    var callback = function() {
+      obj.counter += 1;
+      obj.off('event', callback);
+    };
+    obj.on('event', callback);
+    obj.trigger('event');
+    obj.trigger('event');
+    obj.trigger('event');
+    assert.equal(obj.counter, 1, 'the callback should have been unbound.');
+  });
+
+  QUnit.test('two binds that unbind themeselves', function(assert) {
+    assert.expect(2);
+    var obj = {counterA: 0, counterB: 0};
+    _.extend(obj, Backbone.Events);
+    var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
+    var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };
+    obj.on('event', incrA);
+    obj.on('event', incrB);
+    obj.trigger('event');
+    obj.trigger('event');
+    obj.trigger('event');
+    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
+    assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
+  });
+
+  QUnit.test('bind a callback with a default context when none supplied', function(assert) {
+    assert.expect(1);
+    var obj = _.extend({
+      assertTrue: function() {
+        assert.equal(this, obj, '`this` was bound to the callback');
+      }
+    }, Backbone.Events);
+
+    obj.once('event', obj.assertTrue);
+    obj.trigger('event');
+  });
+
+  QUnit.test('bind a callback with a supplied context', function(assert) {
+    assert.expect(1);
+    var TestClass = function() {
+      return this;
+    };
+    TestClass.prototype.assertTrue = function() {
+      assert.ok(true, '`this` was bound to the callback');
+    };
+
+    var obj = _.extend({}, Backbone.Events);
+    obj.on('event', function() { this.assertTrue(); }, new TestClass);
+    obj.trigger('event');
+  });
+
+  QUnit.test('nested trigger with unbind', function(assert) {
+    assert.expect(1);
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+    var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
+    var incr2 = function(){ obj.counter += 1; };
+    obj.on('event', incr1);
+    obj.on('event', incr2);
+    obj.trigger('event');
+    assert.equal(obj.counter, 3, 'counter should have been incremented three times');
+  });
+
+  QUnit.test('callback list is not altered during trigger', function(assert) {
+    assert.expect(2);
+    var counter = 0, obj = _.extend({}, Backbone.Events);
+    var incr = function(){ counter++; };
+    var incrOn = function(){ obj.on('event all', incr); };
+    var incrOff = function(){ obj.off('event all', incr); };
+
+    obj.on('event all', incrOn).trigger('event');
+    assert.equal(counter, 0, 'on does not alter callback list');
+
+    obj.off().on('event', incrOff).on('event all', incr).trigger('event');
+    assert.equal(counter, 2, 'off does not alter callback list');
+  });
+
+  QUnit.test("#1282 - 'all' callback list is retrieved after each event.", function(assert) {
+    assert.expect(1);
+    var counter = 0;
+    var obj = _.extend({}, Backbone.Events);
+    var incr = function(){ counter++; };
+    obj.on('x', function() {
+      obj.on('y', incr).on('all', incr);
+    })
+    .trigger('x y');
+    assert.strictEqual(counter, 2);
+  });
+
+  QUnit.test('if no callback is provided, `on` is a noop', function(assert) {
+    assert.expect(0);
+    _.extend({}, Backbone.Events).on('test').trigger('test');
+  });
+
+  QUnit.test('if callback is truthy but not a function, `on` should throw an error just like jQuery', function(assert) {
+    assert.expect(1);
+    var view = _.extend({}, Backbone.Events).on('test', 'noop');
+    assert.raises(function() {
+      view.trigger('test');
+    });
+  });
+
+  QUnit.test('remove all events for a specific context', function(assert) {
+    assert.expect(4);
+    var obj = _.extend({}, Backbone.Events);
+    obj.on('x y all', function() { assert.ok(true); });
+    obj.on('x y all', function() { assert.ok(false); }, obj);
+    obj.off(null, null, obj);
+    obj.trigger('x y');
+  });
+
+  QUnit.test('remove all events for a specific callback', function(assert) {
+    assert.expect(4);
+    var obj = _.extend({}, Backbone.Events);
+    var success = function() { assert.ok(true); };
+    var fail = function() { assert.ok(false); };
+    obj.on('x y all', success);
+    obj.on('x y all', fail);
+    obj.off(null, fail);
+    obj.trigger('x y');
+  });
+
+  QUnit.test('#1310 - off does not skip consecutive events', function(assert) {
+    assert.expect(0);
+    var obj = _.extend({}, Backbone.Events);
+    obj.on('event', function() { assert.ok(false); }, obj);
+    obj.on('event', function() { assert.ok(false); }, obj);
+    obj.off(null, null, obj);
+    obj.trigger('event');
+  });
+
+  QUnit.test('once', function(assert) {
+    assert.expect(2);
+    // Same as the previous test, but we use once rather than having to explicitly unbind
+    var obj = {counterA: 0, counterB: 0};
+    _.extend(obj, Backbone.Events);
+    var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
+    var incrB = function(){ obj.counterB += 1; };
+    obj.once('event', incrA);
+    obj.once('event', incrB);
+    obj.trigger('event');
+    assert.equal(obj.counterA, 1, 'counterA should have only been incremented once.');
+    assert.equal(obj.counterB, 1, 'counterB should have only been incremented once.');
+  });
+
+  QUnit.test('once variant one', function(assert) {
+    assert.expect(3);
+    var f = function(){ assert.ok(true); };
+
+    var a = _.extend({}, Backbone.Events).once('event', f);
+    var b = _.extend({}, Backbone.Events).on('event', f);
+
+    a.trigger('event');
+
+    b.trigger('event');
+    b.trigger('event');
+  });
+
+  QUnit.test('once variant two', function(assert) {
+    assert.expect(3);
+    var f = function(){ assert.ok(true); };
+    var obj = _.extend({}, Backbone.Events);
+
+    obj
+      .once('event', f)
+      .on('event', f)
+      .trigger('event')
+      .trigger('event');
+  });
+
+  QUnit.test('once with off', function(assert) {
+    assert.expect(0);
+    var f = function(){ assert.ok(true); };
+    var obj = _.extend({}, Backbone.Events);
+
+    obj.once('event', f);
+    obj.off('event', f);
+    obj.trigger('event');
+  });
+
+  QUnit.test('once with event maps', function(assert) {
+    var obj = {counter: 0};
+    _.extend(obj, Backbone.Events);
+
+    var increment = function() {
+      this.counter += 1;
+    };
+
+    obj.once({
+      a: increment,
+      b: increment,
+      c: increment
+    }, obj);
+
+    obj.trigger('a');
+    assert.equal(obj.counter, 1);
+
+    obj.trigger('a b');
+    assert.equal(obj.counter, 2);
+
+    obj.trigger('c');
+    assert.equal(obj.counter, 3);
+
+    obj.trigger('a b c');
+    assert.equal(obj.counter, 3);
+  });
+
+  QUnit.test('bind a callback with a supplied context using once with object notation', function(assert) {
+    assert.expect(1);
+    var obj = {counter: 0};
+    var context = {};
+    _.extend(obj, Backbone.Events);
+
+    obj.once({
+      a: function() {
+        assert.strictEqual(this, context, 'defaults `context` to `callback` param');
+      }
+    }, context).trigger('a');
+  });
+
+  QUnit.test('once with off only by context', function(assert) {
+    assert.expect(0);
+    var context = {};
+    var obj = _.extend({}, Backbone.Events);
+    obj.once('event', function(){ assert.ok(false); }, context);
+    obj.off(null, null, context);
+    obj.trigger('event');
+  });
+
+  QUnit.test('Backbone object inherits Events', function(assert) {
+    assert.ok(Backbone.on === Backbone.Events.on);
+  });
+
+  QUnit.test('once with asynchronous events', function(assert) {
+    var done = assert.async();
+    assert.expect(1);
+    var func = _.debounce(function() { assert.ok(true); done(); }, 50);
+    var obj = _.extend({}, Backbone.Events).once('async', func);
+
+    obj.trigger('async');
+    obj.trigger('async');
+  });
+
+  QUnit.test('once with multiple events.', function(assert) {
+    assert.expect(2);
+    var obj = _.extend({}, Backbone.Events);
+    obj.once('x y', function() { assert.ok(true); });
+    obj.trigger('x y');
+  });
+
+  QUnit.test('Off during iteration with once.', function(assert) {
+    assert.expect(2);
+    var obj = _.extend({}, Backbone.Events);
+    var f = function(){ this.off('event', f); };
+    obj.on('event', f);
+    obj.once('event', function(){});
+    obj.on('event', function(){ assert.ok(true); });
+
+    obj.trigger('event');
+    obj.trigger('event');
+  });
+
+  QUnit.test('`once` on `all` should work as expected', function(assert) {
+    assert.expect(1);
+    Backbone.once('all', function() {
+      assert.ok(true);
+      Backbone.trigger('all');
+    });
+    Backbone.trigger('all');
+  });
+
+  QUnit.test('once without a callback is a noop', function(assert) {
+    assert.expect(0);
+    _.extend({}, Backbone.Events).once('event').trigger('event');
+  });
+
+  QUnit.test('listenToOnce without a callback is a noop', function(assert) {
+    assert.expect(0);
+    var obj = _.extend({}, Backbone.Events);
+    obj.listenToOnce(obj, 'event').trigger('event');
+  });
+
+  QUnit.test('event functions are chainable', function(assert) {
+    var obj = _.extend({}, Backbone.Events);
+    var obj2 = _.extend({}, Backbone.Events);
+    var fn = function() {};
+    assert.equal(obj, obj.trigger('noeventssetyet'));
+    assert.equal(obj, obj.off('noeventssetyet'));
+    assert.equal(obj, obj.stopListening('noeventssetyet'));
+    assert.equal(obj, obj.on('a', fn));
+    assert.equal(obj, obj.once('c', fn));
+    assert.equal(obj, obj.trigger('a'));
+    assert.equal(obj, obj.listenTo(obj2, 'a', fn));
+    assert.equal(obj, obj.listenToOnce(obj2, 'b', fn));
+    assert.equal(obj, obj.off('a c'));
+    assert.equal(obj, obj.stopListening(obj2, 'a'));
+    assert.equal(obj, obj.stopListening());
+  });
+
+  QUnit.test('#3448 - listenToOnce with space-separated events', function(assert) {
+    assert.expect(2);
+    var one = _.extend({}, Backbone.Events);
+    var two = _.extend({}, Backbone.Events);
+    var count = 1;
+    one.listenToOnce(two, 'x y', function(n) { assert.ok(n === count++); });
+    two.trigger('x', 1);
+    two.trigger('x', 1);
+    two.trigger('y', 2);
+    two.trigger('y', 2);
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/model.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/model.js
new file mode 100644
index 0000000..b73a1c7
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/model.js
@@ -0,0 +1,1418 @@
+(function() {
+
+  var ProxyModel = Backbone.Model.extend();
+  var Klass = Backbone.Collection.extend({
+    url: function() { return '/collection'; }
+  });
+  var doc, collection;
+
+  QUnit.module('Backbone.Model', {
+
+    beforeEach: function(assert) {
+      doc = new ProxyModel({
+        id: '1-the-tempest',
+        title: 'The Tempest',
+        author: 'Bill Shakespeare',
+        length: 123
+      });
+      collection = new Klass();
+      collection.add(doc);
+    }
+
+  });
+
+  QUnit.test('initialize', function(assert) {
+    assert.expect(3);
+    var Model = Backbone.Model.extend({
+      initialize: function() {
+        this.one = 1;
+        assert.equal(this.collection, collection);
+      }
+    });
+    var model = new Model({}, {collection: collection});
+    assert.equal(model.one, 1);
+    assert.equal(model.collection, collection);
+  });
+
+  QUnit.test('Object.prototype properties are overridden by attributes', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({hasOwnProperty: true});
+    assert.equal(model.get('hasOwnProperty'), true);
+  });
+
+  QUnit.test('initialize with attributes and options', function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      initialize: function(attributes, options) {
+        this.one = options.one;
+      }
+    });
+    var model = new Model({}, {one: 1});
+    assert.equal(model.one, 1);
+  });
+
+  QUnit.test('initialize with parsed attributes', function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      parse: function(attrs) {
+        attrs.value += 1;
+        return attrs;
+      }
+    });
+    var model = new Model({value: 1}, {parse: true});
+    assert.equal(model.get('value'), 2);
+  });
+
+  QUnit.test('parse can return null', function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      parse: function(attrs) {
+        attrs.value += 1;
+        return null;
+      }
+    });
+    var model = new Model({value: 1}, {parse: true});
+    assert.equal(JSON.stringify(model.toJSON()), '{}');
+  });
+
+  QUnit.test('url', function(assert) {
+    assert.expect(3);
+    doc.urlRoot = null;
+    assert.equal(doc.url(), '/collection/1-the-tempest');
+    doc.collection.url = '/collection/';
+    assert.equal(doc.url(), '/collection/1-the-tempest');
+    doc.collection = null;
+    assert.raises(function() { doc.url(); });
+    doc.collection = collection;
+  });
+
+  QUnit.test('url when using urlRoot, and uri encoding', function(assert) {
+    assert.expect(2);
+    var Model = Backbone.Model.extend({
+      urlRoot: '/collection'
+    });
+    var model = new Model();
+    assert.equal(model.url(), '/collection');
+    model.set({id: '+1+'});
+    assert.equal(model.url(), '/collection/%2B1%2B');
+  });
+
+  QUnit.test('url when using urlRoot as a function to determine urlRoot at runtime', function(assert) {
+    assert.expect(2);
+    var Model = Backbone.Model.extend({
+      urlRoot: function() {
+        return '/nested/' + this.get('parentId') + '/collection';
+      }
+    });
+
+    var model = new Model({parentId: 1});
+    assert.equal(model.url(), '/nested/1/collection');
+    model.set({id: 2});
+    assert.equal(model.url(), '/nested/1/collection/2');
+  });
+
+  QUnit.test('underscore methods', function(assert) {
+    assert.expect(5);
+    var model = new Backbone.Model({foo: 'a', bar: 'b', baz: 'c'});
+    var model2 = model.clone();
+    assert.deepEqual(model.keys(), ['foo', 'bar', 'baz']);
+    assert.deepEqual(model.values(), ['a', 'b', 'c']);
+    assert.deepEqual(model.invert(), {a: 'foo', b: 'bar', c: 'baz'});
+    assert.deepEqual(model.pick('foo', 'baz'), {foo: 'a', baz: 'c'});
+    assert.deepEqual(model.omit('foo', 'bar'), {baz: 'c'});
+  });
+
+  QUnit.test('chain', function(assert) {
+    var model = new Backbone.Model({a: 0, b: 1, c: 2});
+    assert.deepEqual(model.chain().pick('a', 'b', 'c').values().compact().value(), [1, 2]);
+  });
+
+  QUnit.test('clone', function(assert) {
+    assert.expect(10);
+    var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});
+    var b = a.clone();
+    assert.equal(a.get('foo'), 1);
+    assert.equal(a.get('bar'), 2);
+    assert.equal(a.get('baz'), 3);
+    assert.equal(b.get('foo'), a.get('foo'), 'Foo should be the same on the clone.');
+    assert.equal(b.get('bar'), a.get('bar'), 'Bar should be the same on the clone.');
+    assert.equal(b.get('baz'), a.get('baz'), 'Baz should be the same on the clone.');
+    a.set({foo: 100});
+    assert.equal(a.get('foo'), 100);
+    assert.equal(b.get('foo'), 1, 'Changing a parent attribute does not change the clone.');
+
+    var foo = new Backbone.Model({p: 1});
+    var bar = new Backbone.Model({p: 2});
+    bar.set(foo.clone().attributes, {unset: true});
+    assert.equal(foo.get('p'), 1);
+    assert.equal(bar.get('p'), undefined);
+  });
+
+  QUnit.test('isNew', function(assert) {
+    assert.expect(6);
+    var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});
+    assert.ok(a.isNew(), 'it should be new');
+    a = new Backbone.Model({foo: 1, bar: 2, baz: 3, id: -5});
+    assert.ok(!a.isNew(), 'any defined ID is legal, negative or positive');
+    a = new Backbone.Model({foo: 1, bar: 2, baz: 3, id: 0});
+    assert.ok(!a.isNew(), 'any defined ID is legal, including zero');
+    assert.ok(new Backbone.Model().isNew(), 'is true when there is no id');
+    assert.ok(!new Backbone.Model({id: 2}).isNew(), 'is false for a positive integer');
+    assert.ok(!new Backbone.Model({id: -5}).isNew(), 'is false for a negative integer');
+  });
+
+  QUnit.test('get', function(assert) {
+    assert.expect(2);
+    assert.equal(doc.get('title'), 'The Tempest');
+    assert.equal(doc.get('author'), 'Bill Shakespeare');
+  });
+
+  QUnit.test('escape', function(assert) {
+    assert.expect(5);
+    assert.equal(doc.escape('title'), 'The Tempest');
+    doc.set({audience: 'Bill & Bob'});
+    assert.equal(doc.escape('audience'), 'Bill &amp; Bob');
+    doc.set({audience: 'Tim > Joan'});
+    assert.equal(doc.escape('audience'), 'Tim &gt; Joan');
+    doc.set({audience: 10101});
+    assert.equal(doc.escape('audience'), '10101');
+    doc.unset('audience');
+    assert.equal(doc.escape('audience'), '');
+  });
+
+  QUnit.test('has', function(assert) {
+    assert.expect(10);
+    var model = new Backbone.Model();
+
+    assert.strictEqual(model.has('name'), false);
+
+    model.set({
+      '0': 0,
+      '1': 1,
+      'true': true,
+      'false': false,
+      'empty': '',
+      'name': 'name',
+      'null': null,
+      'undefined': undefined
+    });
+
+    assert.strictEqual(model.has('0'), true);
+    assert.strictEqual(model.has('1'), true);
+    assert.strictEqual(model.has('true'), true);
+    assert.strictEqual(model.has('false'), true);
+    assert.strictEqual(model.has('empty'), true);
+    assert.strictEqual(model.has('name'), true);
+
+    model.unset('name');
+
+    assert.strictEqual(model.has('name'), false);
+    assert.strictEqual(model.has('null'), false);
+    assert.strictEqual(model.has('undefined'), false);
+  });
+
+  QUnit.test('matches', function(assert) {
+    assert.expect(4);
+    var model = new Backbone.Model();
+
+    assert.strictEqual(model.matches({name: 'Jonas', cool: true}), false);
+
+    model.set({name: 'Jonas', cool: true});
+
+    assert.strictEqual(model.matches({name: 'Jonas'}), true);
+    assert.strictEqual(model.matches({name: 'Jonas', cool: true}), true);
+    assert.strictEqual(model.matches({name: 'Jonas', cool: false}), false);
+  });
+
+  QUnit.test('matches with predicate', function(assert) {
+    var model = new Backbone.Model({a: 0});
+
+    assert.strictEqual(model.matches(function(attr) {
+      return attr.a > 1 && attr.b != null;
+    }), false);
+
+    model.set({a: 3, b: true});
+
+    assert.strictEqual(model.matches(function(attr) {
+      return attr.a > 1 && attr.b != null;
+    }), true);
+  });
+
+  QUnit.test('set and unset', function(assert) {
+    assert.expect(8);
+    var a = new Backbone.Model({id: 'id', foo: 1, bar: 2, baz: 3});
+    var changeCount = 0;
+    a.on('change:foo', function() { changeCount += 1; });
+    a.set({foo: 2});
+    assert.equal(a.get('foo'), 2, 'Foo should have changed.');
+    assert.equal(changeCount, 1, 'Change count should have incremented.');
+    // set with value that is not new shouldn't fire change event
+    a.set({foo: 2});
+    assert.equal(a.get('foo'), 2, 'Foo should NOT have changed, still 2');
+    assert.equal(changeCount, 1, 'Change count should NOT have incremented.');
+
+    a.validate = function(attrs) {
+      assert.equal(attrs.foo, void 0, 'validate:true passed while unsetting');
+    };
+    a.unset('foo', {validate: true});
+    assert.equal(a.get('foo'), void 0, 'Foo should have changed');
+    delete a.validate;
+    assert.equal(changeCount, 2, 'Change count should have incremented for unset.');
+
+    a.unset('id');
+    assert.equal(a.id, undefined, 'Unsetting the id should remove the id property.');
+  });
+
+  QUnit.test('#2030 - set with failed validate, followed by another set triggers change', function(assert) {
+    var attr = 0, main = 0, error = 0;
+    var Model = Backbone.Model.extend({
+      validate: function(attrs) {
+        if (attrs.x > 1) {
+          error++;
+          return 'this is an error';
+        }
+      }
+    });
+    var model = new Model({x: 0});
+    model.on('change:x', function() { attr++; });
+    model.on('change', function() { main++; });
+    model.set({x: 2}, {validate: true});
+    model.set({x: 1}, {validate: true});
+    assert.deepEqual([attr, main, error], [1, 1, 1]);
+  });
+
+  QUnit.test('set triggers changes in the correct order', function(assert) {
+    var value = null;
+    var model = new Backbone.Model;
+    model.on('last', function(){ value = 'last'; });
+    model.on('first', function(){ value = 'first'; });
+    model.trigger('first');
+    model.trigger('last');
+    assert.equal(value, 'last');
+  });
+
+  QUnit.test('set falsy values in the correct order', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model({result: 'result'});
+    model.on('change', function() {
+      assert.equal(model.changed.result, void 0);
+      assert.equal(model.previous('result'), false);
+    });
+    model.set({result: void 0}, {silent: true});
+    model.set({result: null}, {silent: true});
+    model.set({result: false}, {silent: true});
+    model.set({result: void 0});
+  });
+
+  QUnit.test('nested set triggers with the correct options', function(assert) {
+    var model = new Backbone.Model();
+    var o1 = {};
+    var o2 = {};
+    var o3 = {};
+    model.on('change', function(__, options) {
+      switch (model.get('a')) {
+        case 1:
+          assert.equal(options, o1);
+          return model.set('a', 2, o2);
+        case 2:
+          assert.equal(options, o2);
+          return model.set('a', 3, o3);
+        case 3:
+          assert.equal(options, o3);
+      }
+    });
+    model.set('a', 1, o1);
+  });
+
+  QUnit.test('multiple unsets', function(assert) {
+    assert.expect(1);
+    var i = 0;
+    var counter = function(){ i++; };
+    var model = new Backbone.Model({a: 1});
+    model.on('change:a', counter);
+    model.set({a: 2});
+    model.unset('a');
+    model.unset('a');
+    assert.equal(i, 2, 'Unset does not fire an event for missing attributes.');
+  });
+
+  QUnit.test('unset and changedAttributes', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({a: 1});
+    model.on('change', function() {
+      assert.ok('a' in model.changedAttributes(), 'changedAttributes should contain unset properties');
+    });
+    model.unset('a');
+  });
+
+  QUnit.test('using a non-default id attribute.', function(assert) {
+    assert.expect(5);
+    var MongoModel = Backbone.Model.extend({idAttribute: '_id'});
+    var model = new MongoModel({id: 'eye-dee', _id: 25, title: 'Model'});
+    assert.equal(model.get('id'), 'eye-dee');
+    assert.equal(model.id, 25);
+    assert.equal(model.isNew(), false);
+    model.unset('_id');
+    assert.equal(model.id, undefined);
+    assert.equal(model.isNew(), true);
+  });
+
+  QUnit.test('setting an alternative cid prefix', function(assert) {
+    assert.expect(4);
+    var Model = Backbone.Model.extend({
+      cidPrefix: 'm'
+    });
+    var model = new Model();
+
+    assert.equal(model.cid.charAt(0), 'm');
+
+    model = new Backbone.Model();
+    assert.equal(model.cid.charAt(0), 'c');
+
+    var Collection = Backbone.Collection.extend({
+      model: Model
+    });
+    var col = new Collection([{id: 'c5'}, {id: 'c6'}, {id: 'c7'}]);
+
+    assert.equal(col.get('c6').cid.charAt(0), 'm');
+    col.set([{id: 'c6', value: 'test'}], {
+      merge: true,
+      add: true,
+      remove: false
+    });
+    assert.ok(col.get('c6').has('value'));
+  });
+
+  QUnit.test('set an empty string', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({name: 'Model'});
+    model.set({name: ''});
+    assert.equal(model.get('name'), '');
+  });
+
+  QUnit.test('setting an object', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({
+      custom: {foo: 1}
+    });
+    model.on('change', function() {
+      assert.ok(1);
+    });
+    model.set({
+      custom: {foo: 1} // no change should be fired
+    });
+    model.set({
+      custom: {foo: 2} // change event should be fired
+    });
+  });
+
+  QUnit.test('clear', function(assert) {
+    assert.expect(3);
+    var changed;
+    var model = new Backbone.Model({id: 1, name: 'Model'});
+    model.on('change:name', function(){ changed = true; });
+    model.on('change', function() {
+      var changedAttrs = model.changedAttributes();
+      assert.ok('name' in changedAttrs);
+    });
+    model.clear();
+    assert.equal(changed, true);
+    assert.equal(model.get('name'), undefined);
+  });
+
+  QUnit.test('defaults', function(assert) {
+    assert.expect(9);
+    var Defaulted = Backbone.Model.extend({
+      defaults: {
+        one: 1,
+        two: 2
+      }
+    });
+    var model = new Defaulted({two: undefined});
+    assert.equal(model.get('one'), 1);
+    assert.equal(model.get('two'), 2);
+    model = new Defaulted({two: 3});
+    assert.equal(model.get('one'), 1);
+    assert.equal(model.get('two'), 3);
+    Defaulted = Backbone.Model.extend({
+      defaults: function() {
+        return {
+          one: 3,
+          two: 4
+        };
+      }
+    });
+    model = new Defaulted({two: undefined});
+    assert.equal(model.get('one'), 3);
+    assert.equal(model.get('two'), 4);
+    Defaulted = Backbone.Model.extend({
+      defaults: {hasOwnProperty: true}
+    });
+    model = new Defaulted();
+    assert.equal(model.get('hasOwnProperty'), true);
+    model = new Defaulted({hasOwnProperty: undefined});
+    assert.equal(model.get('hasOwnProperty'), true);
+    model = new Defaulted({hasOwnProperty: false});
+    assert.equal(model.get('hasOwnProperty'), false);
+  });
+
+  QUnit.test('change, hasChanged, changedAttributes, previous, previousAttributes', function(assert) {
+    assert.expect(9);
+    var model = new Backbone.Model({name: 'Tim', age: 10});
+    assert.deepEqual(model.changedAttributes(), false);
+    model.on('change', function() {
+      assert.ok(model.hasChanged('name'), 'name changed');
+      assert.ok(!model.hasChanged('age'), 'age did not');
+      assert.ok(_.isEqual(model.changedAttributes(), {name: 'Rob'}), 'changedAttributes returns the changed attrs');
+      assert.equal(model.previous('name'), 'Tim');
+      assert.ok(_.isEqual(model.previousAttributes(), {name: 'Tim', age: 10}), 'previousAttributes is correct');
+    });
+    assert.equal(model.hasChanged(), false);
+    assert.equal(model.hasChanged(undefined), false);
+    model.set({name: 'Rob'});
+    assert.equal(model.get('name'), 'Rob');
+  });
+
+  QUnit.test('changedAttributes', function(assert) {
+    assert.expect(3);
+    var model = new Backbone.Model({a: 'a', b: 'b'});
+    assert.deepEqual(model.changedAttributes(), false);
+    assert.equal(model.changedAttributes({a: 'a'}), false);
+    assert.equal(model.changedAttributes({a: 'b'}).a, 'b');
+  });
+
+  QUnit.test('change with options', function(assert) {
+    assert.expect(2);
+    var value;
+    var model = new Backbone.Model({name: 'Rob'});
+    model.on('change', function(m, options) {
+      value = options.prefix + m.get('name');
+    });
+    model.set({name: 'Bob'}, {prefix: 'Mr. '});
+    assert.equal(value, 'Mr. Bob');
+    model.set({name: 'Sue'}, {prefix: 'Ms. '});
+    assert.equal(value, 'Ms. Sue');
+  });
+
+  QUnit.test('change after initialize', function(assert) {
+    assert.expect(1);
+    var changed = 0;
+    var attrs = {id: 1, label: 'c'};
+    var obj = new Backbone.Model(attrs);
+    obj.on('change', function() { changed += 1; });
+    obj.set(attrs);
+    assert.equal(changed, 0);
+  });
+
+  QUnit.test('save within change event', function(assert) {
+    assert.expect(1);
+    var env = this;
+    var model = new Backbone.Model({firstName: 'Taylor', lastName: 'Swift'});
+    model.url = '/test';
+    model.on('change', function() {
+      model.save();
+      assert.ok(_.isEqual(env.syncArgs.model, model));
+    });
+    model.set({lastName: 'Hicks'});
+  });
+
+  QUnit.test('validate after save', function(assert) {
+    assert.expect(2);
+    var lastError, model = new Backbone.Model();
+    model.validate = function(attrs) {
+      if (attrs.admin) return "Can't change admin status.";
+    };
+    model.sync = function(method, m, options) {
+      options.success.call(this, {admin: true});
+    };
+    model.on('invalid', function(m, error) {
+      lastError = error;
+    });
+    model.save(null);
+
+    assert.equal(lastError, "Can't change admin status.");
+    assert.equal(model.validationError, "Can't change admin status.");
+  });
+
+  QUnit.test('save', function(assert) {
+    assert.expect(2);
+    doc.save({title: 'Henry V'});
+    assert.equal(this.syncArgs.method, 'update');
+    assert.ok(_.isEqual(this.syncArgs.model, doc));
+  });
+
+  QUnit.test('save, fetch, destroy triggers error event when an error occurs', function(assert) {
+    assert.expect(3);
+    var model = new Backbone.Model();
+    model.on('error', function() {
+      assert.ok(true);
+    });
+    model.sync = function(method, m, options) {
+      options.error();
+    };
+    model.save({data: 2, id: 1});
+    model.fetch();
+    model.destroy();
+  });
+
+  QUnit.test('#3283 - save, fetch, destroy calls success with context', function(assert) {
+    assert.expect(3);
+    var model = new Backbone.Model();
+    var obj = {};
+    var options = {
+      context: obj,
+      success: function() {
+        assert.equal(this, obj);
+      }
+    };
+    model.sync = function(method, m, opts) {
+      opts.success.call(opts.context);
+    };
+    model.save({data: 2, id: 1}, options);
+    model.fetch(options);
+    model.destroy(options);
+  });
+
+  QUnit.test('#3283 - save, fetch, destroy calls error with context', function(assert) {
+    assert.expect(3);
+    var model = new Backbone.Model();
+    var obj = {};
+    var options = {
+      context: obj,
+      error: function() {
+        assert.equal(this, obj);
+      }
+    };
+    model.sync = function(method, m, opts) {
+      opts.error.call(opts.context);
+    };
+    model.save({data: 2, id: 1}, options);
+    model.fetch(options);
+    model.destroy(options);
+  });
+
+  QUnit.test('#3470 - save and fetch with parse false', function(assert) {
+    assert.expect(2);
+    var i = 0;
+    var model = new Backbone.Model();
+    model.parse = function() {
+      assert.ok(false);
+    };
+    model.sync = function(method, m, options) {
+      options.success({i: ++i});
+    };
+    model.fetch({parse: false});
+    assert.equal(model.get('i'), i);
+    model.save(null, {parse: false});
+    assert.equal(model.get('i'), i);
+  });
+
+  QUnit.test('save with PATCH', function(assert) {
+    doc.clear().set({id: 1, a: 1, b: 2, c: 3, d: 4});
+    doc.save();
+    assert.equal(this.syncArgs.method, 'update');
+    assert.equal(this.syncArgs.options.attrs, undefined);
+
+    doc.save({b: 2, d: 4}, {patch: true});
+    assert.equal(this.syncArgs.method, 'patch');
+    assert.equal(_.size(this.syncArgs.options.attrs), 2);
+    assert.equal(this.syncArgs.options.attrs.d, 4);
+    assert.equal(this.syncArgs.options.attrs.a, undefined);
+    assert.equal(this.ajaxSettings.data, '{"b":2,"d":4}');
+  });
+
+  QUnit.test('save with PATCH and different attrs', function(assert) {
+    doc.clear().save({b: 2, d: 4}, {patch: true, attrs: {B: 1, D: 3}});
+    assert.equal(this.syncArgs.options.attrs.D, 3);
+    assert.equal(this.syncArgs.options.attrs.d, undefined);
+    assert.equal(this.ajaxSettings.data, '{"B":1,"D":3}');
+    assert.deepEqual(doc.attributes, {b: 2, d: 4});
+  });
+
+  QUnit.test('save in positional style', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.sync = function(method, m, options) {
+      options.success();
+    };
+    model.save('title', 'Twelfth Night');
+    assert.equal(model.get('title'), 'Twelfth Night');
+  });
+
+  QUnit.test('save with non-object success response', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model();
+    model.sync = function(method, m, options) {
+      options.success('', options);
+      options.success(null, options);
+    };
+    model.save({testing: 'empty'}, {
+      success: function(m) {
+        assert.deepEqual(m.attributes, {testing: 'empty'});
+      }
+    });
+  });
+
+  QUnit.test('save with wait and supplied id', function(assert) {
+    var Model = Backbone.Model.extend({
+      urlRoot: '/collection'
+    });
+    var model = new Model();
+    model.save({id: 42}, {wait: true});
+    assert.equal(this.ajaxSettings.url, '/collection/42');
+  });
+
+  QUnit.test('save will pass extra options to success callback', function(assert) {
+    assert.expect(1);
+    var SpecialSyncModel = Backbone.Model.extend({
+      sync: function(method, m, options) {
+        _.extend(options, {specialSync: true});
+        return Backbone.Model.prototype.sync.call(this, method, m, options);
+      },
+      urlRoot: '/test'
+    });
+
+    var model = new SpecialSyncModel();
+
+    var onSuccess = function(m, response, options) {
+      assert.ok(options.specialSync, 'Options were passed correctly to callback');
+    };
+
+    model.save(null, {success: onSuccess});
+    this.ajaxSettings.success();
+  });
+
+  QUnit.test('fetch', function(assert) {
+    assert.expect(2);
+    doc.fetch();
+    assert.equal(this.syncArgs.method, 'read');
+    assert.ok(_.isEqual(this.syncArgs.model, doc));
+  });
+
+  QUnit.test('fetch will pass extra options to success callback', function(assert) {
+    assert.expect(1);
+    var SpecialSyncModel = Backbone.Model.extend({
+      sync: function(method, m, options) {
+        _.extend(options, {specialSync: true});
+        return Backbone.Model.prototype.sync.call(this, method, m, options);
+      },
+      urlRoot: '/test'
+    });
+
+    var model = new SpecialSyncModel();
+
+    var onSuccess = function(m, response, options) {
+      assert.ok(options.specialSync, 'Options were passed correctly to callback');
+    };
+
+    model.fetch({success: onSuccess});
+    this.ajaxSettings.success();
+  });
+
+  QUnit.test('destroy', function(assert) {
+    assert.expect(3);
+    doc.destroy();
+    assert.equal(this.syncArgs.method, 'delete');
+    assert.ok(_.isEqual(this.syncArgs.model, doc));
+
+    var newModel = new Backbone.Model;
+    assert.equal(newModel.destroy(), false);
+  });
+
+  QUnit.test('destroy will pass extra options to success callback', function(assert) {
+    assert.expect(1);
+    var SpecialSyncModel = Backbone.Model.extend({
+      sync: function(method, m, options) {
+        _.extend(options, {specialSync: true});
+        return Backbone.Model.prototype.sync.call(this, method, m, options);
+      },
+      urlRoot: '/test'
+    });
+
+    var model = new SpecialSyncModel({id: 'id'});
+
+    var onSuccess = function(m, response, options) {
+      assert.ok(options.specialSync, 'Options were passed correctly to callback');
+    };
+
+    model.destroy({success: onSuccess});
+    this.ajaxSettings.success();
+  });
+
+  QUnit.test('non-persisted destroy', function(assert) {
+    assert.expect(1);
+    var a = new Backbone.Model({foo: 1, bar: 2, baz: 3});
+    a.sync = function() { throw 'should not be called'; };
+    a.destroy();
+    assert.ok(true, 'non-persisted model should not call sync');
+  });
+
+  QUnit.test('validate', function(assert) {
+    var lastError;
+    var model = new Backbone.Model();
+    model.validate = function(attrs) {
+      if (attrs.admin !== this.get('admin')) return "Can't change admin status.";
+    };
+    model.on('invalid', function(m, error) {
+      lastError = error;
+    });
+    var result = model.set({a: 100});
+    assert.equal(result, model);
+    assert.equal(model.get('a'), 100);
+    assert.equal(lastError, undefined);
+    result = model.set({admin: true});
+    assert.equal(model.get('admin'), true);
+    result = model.set({a: 200, admin: false}, {validate: true});
+    assert.equal(lastError, "Can't change admin status.");
+    assert.equal(result, false);
+    assert.equal(model.get('a'), 100);
+  });
+
+  QUnit.test('validate on unset and clear', function(assert) {
+    assert.expect(6);
+    var error;
+    var model = new Backbone.Model({name: 'One'});
+    model.validate = function(attrs) {
+      if (!attrs.name) {
+        error = true;
+        return 'No thanks.';
+      }
+    };
+    model.set({name: 'Two'});
+    assert.equal(model.get('name'), 'Two');
+    assert.equal(error, undefined);
+    model.unset('name', {validate: true});
+    assert.equal(error, true);
+    assert.equal(model.get('name'), 'Two');
+    model.clear({validate: true});
+    assert.equal(model.get('name'), 'Two');
+    delete model.validate;
+    model.clear();
+    assert.equal(model.get('name'), undefined);
+  });
+
+  QUnit.test('validate with error callback', function(assert) {
+    assert.expect(8);
+    var lastError, boundError;
+    var model = new Backbone.Model();
+    model.validate = function(attrs) {
+      if (attrs.admin) return "Can't change admin status.";
+    };
+    model.on('invalid', function(m, error) {
+      boundError = true;
+    });
+    var result = model.set({a: 100}, {validate: true});
+    assert.equal(result, model);
+    assert.equal(model.get('a'), 100);
+    assert.equal(model.validationError, null);
+    assert.equal(boundError, undefined);
+    result = model.set({a: 200, admin: true}, {validate: true});
+    assert.equal(result, false);
+    assert.equal(model.get('a'), 100);
+    assert.equal(model.validationError, "Can't change admin status.");
+    assert.equal(boundError, true);
+  });
+
+  QUnit.test('defaults always extend attrs (#459)', function(assert) {
+    assert.expect(2);
+    var Defaulted = Backbone.Model.extend({
+      defaults: {one: 1},
+      initialize: function(attrs, opts) {
+        assert.equal(this.attributes.one, 1);
+      }
+    });
+    var providedattrs = new Defaulted({});
+    var emptyattrs = new Defaulted();
+  });
+
+  QUnit.test('Inherit class properties', function(assert) {
+    assert.expect(6);
+    var Parent = Backbone.Model.extend({
+      instancePropSame: function() {},
+      instancePropDiff: function() {}
+    }, {
+      classProp: function() {}
+    });
+    var Child = Parent.extend({
+      instancePropDiff: function() {}
+    });
+
+    var adult = new Parent;
+    var kid   = new Child;
+
+    assert.equal(Child.classProp, Parent.classProp);
+    assert.notEqual(Child.classProp, undefined);
+
+    assert.equal(kid.instancePropSame, adult.instancePropSame);
+    assert.notEqual(kid.instancePropSame, undefined);
+
+    assert.notEqual(Child.prototype.instancePropDiff, Parent.prototype.instancePropDiff);
+    assert.notEqual(Child.prototype.instancePropDiff, undefined);
+  });
+
+  QUnit.test("Nested change events don't clobber previous attributes", function(assert) {
+    assert.expect(4);
+    new Backbone.Model()
+    .on('change:state', function(m, newState) {
+      assert.equal(m.previous('state'), undefined);
+      assert.equal(newState, 'hello');
+      // Fire a nested change event.
+      m.set({other: 'whatever'});
+    })
+    .on('change:state', function(m, newState) {
+      assert.equal(m.previous('state'), undefined);
+      assert.equal(newState, 'hello');
+    })
+    .set({state: 'hello'});
+  });
+
+  QUnit.test('hasChanged/set should use same comparison', function(assert) {
+    assert.expect(2);
+    var changed = 0, model = new Backbone.Model({a: null});
+    model.on('change', function() {
+      assert.ok(this.hasChanged('a'));
+    })
+    .on('change:a', function() {
+      changed++;
+    })
+    .set({a: undefined});
+    assert.equal(changed, 1);
+  });
+
+  QUnit.test('#582, #425, change:attribute callbacks should fire after all changes have occurred', function(assert) {
+    assert.expect(9);
+    var model = new Backbone.Model;
+
+    var assertion = function() {
+      assert.equal(model.get('a'), 'a');
+      assert.equal(model.get('b'), 'b');
+      assert.equal(model.get('c'), 'c');
+    };
+
+    model.on('change:a', assertion);
+    model.on('change:b', assertion);
+    model.on('change:c', assertion);
+
+    model.set({a: 'a', b: 'b', c: 'c'});
+  });
+
+  QUnit.test('#871, set with attributes property', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.set({attributes: true});
+    assert.ok(model.has('attributes'));
+  });
+
+  QUnit.test('set value regardless of equality/change', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({x: []});
+    var a = [];
+    model.set({x: a});
+    assert.ok(model.get('x') === a);
+  });
+
+  QUnit.test('set same value does not trigger change', function(assert) {
+    assert.expect(0);
+    var model = new Backbone.Model({x: 1});
+    model.on('change change:x', function() { assert.ok(false); });
+    model.set({x: 1});
+    model.set({x: 1});
+  });
+
+  QUnit.test('unset does not fire a change for undefined attributes', function(assert) {
+    assert.expect(0);
+    var model = new Backbone.Model({x: undefined});
+    model.on('change:x', function(){ assert.ok(false); });
+    model.unset('x');
+  });
+
+  QUnit.test('set: undefined values', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({x: undefined});
+    assert.ok('x' in model.attributes);
+  });
+
+  QUnit.test('hasChanged works outside of change events, and true within', function(assert) {
+    assert.expect(6);
+    var model = new Backbone.Model({x: 1});
+    model.on('change:x', function() {
+      assert.ok(model.hasChanged('x'));
+      assert.equal(model.get('x'), 1);
+    });
+    model.set({x: 2}, {silent: true});
+    assert.ok(model.hasChanged());
+    assert.equal(model.hasChanged('x'), true);
+    model.set({x: 1});
+    assert.ok(model.hasChanged());
+    assert.equal(model.hasChanged('x'), true);
+  });
+
+  QUnit.test('hasChanged gets cleared on the following set', function(assert) {
+    assert.expect(4);
+    var model = new Backbone.Model;
+    model.set({x: 1});
+    assert.ok(model.hasChanged());
+    model.set({x: 1});
+    assert.ok(!model.hasChanged());
+    model.set({x: 2});
+    assert.ok(model.hasChanged());
+    model.set({});
+    assert.ok(!model.hasChanged());
+  });
+
+  QUnit.test('save with `wait` succeeds without `validate`', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.url = '/test';
+    model.save({x: 1}, {wait: true});
+    assert.ok(this.syncArgs.model === model);
+  });
+
+  QUnit.test("save without `wait` doesn't set invalid attributes", function(assert) {
+    var model = new Backbone.Model();
+    model.validate = function() { return 1; };
+    model.save({a: 1});
+    assert.equal(model.get('a'), void 0);
+  });
+
+  QUnit.test("save doesn't validate twice", function(assert) {
+    var model = new Backbone.Model();
+    var times = 0;
+    model.sync = function() {};
+    model.validate = function() { ++times; };
+    model.save({});
+    assert.equal(times, 1);
+  });
+
+  QUnit.test('`hasChanged` for falsey keys', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model();
+    model.set({x: true}, {silent: true});
+    assert.ok(!model.hasChanged(0));
+    assert.ok(!model.hasChanged(''));
+  });
+
+  QUnit.test('`previous` for falsey keys', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model({'0': true, '': true});
+    model.set({'0': false, '': false}, {silent: true});
+    assert.equal(model.previous(0), true);
+    assert.equal(model.previous(''), true);
+  });
+
+  QUnit.test('`save` with `wait` sends correct attributes', function(assert) {
+    assert.expect(5);
+    var changed = 0;
+    var model = new Backbone.Model({x: 1, y: 2});
+    model.url = '/test';
+    model.on('change:x', function() { changed++; });
+    model.save({x: 3}, {wait: true});
+    assert.deepEqual(JSON.parse(this.ajaxSettings.data), {x: 3, y: 2});
+    assert.equal(model.get('x'), 1);
+    assert.equal(changed, 0);
+    this.syncArgs.options.success({});
+    assert.equal(model.get('x'), 3);
+    assert.equal(changed, 1);
+  });
+
+  QUnit.test("a failed `save` with `wait` doesn't leave attributes behind", function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model;
+    model.url = '/test';
+    model.save({x: 1}, {wait: true});
+    assert.equal(model.get('x'), void 0);
+  });
+
+  QUnit.test('#1030 - `save` with `wait` results in correct attributes if success is called during sync', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model({x: 1, y: 2});
+    model.sync = function(method, m, options) {
+      options.success();
+    };
+    model.on('change:x', function() { assert.ok(true); });
+    model.save({x: 3}, {wait: true});
+    assert.equal(model.get('x'), 3);
+  });
+
+  QUnit.test('save with wait validates attributes', function(assert) {
+    var model = new Backbone.Model();
+    model.url = '/test';
+    model.validate = function() { assert.ok(true); };
+    model.save({x: 1}, {wait: true});
+  });
+
+  QUnit.test('save turns on parse flag', function(assert) {
+    var Model = Backbone.Model.extend({
+      sync: function(method, m, options) { assert.ok(options.parse); }
+    });
+    new Model().save();
+  });
+
+  QUnit.test("nested `set` during `'change:attr'`", function(assert) {
+    assert.expect(2);
+    var events = [];
+    var model = new Backbone.Model();
+    model.on('all', function(event) { events.push(event); });
+    model.on('change', function() {
+      model.set({z: true}, {silent: true});
+    });
+    model.on('change:x', function() {
+      model.set({y: true});
+    });
+    model.set({x: true});
+    assert.deepEqual(events, ['change:y', 'change:x', 'change']);
+    events = [];
+    model.set({z: true});
+    assert.deepEqual(events, []);
+  });
+
+  QUnit.test('nested `change` only fires once', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.on('change', function() {
+      assert.ok(true);
+      model.set({x: true});
+    });
+    model.set({x: true});
+  });
+
+  QUnit.test("nested `set` during `'change'`", function(assert) {
+    assert.expect(6);
+    var count = 0;
+    var model = new Backbone.Model();
+    model.on('change', function() {
+      switch (count++) {
+        case 0:
+          assert.deepEqual(this.changedAttributes(), {x: true});
+          assert.equal(model.previous('x'), undefined);
+          model.set({y: true});
+          break;
+        case 1:
+          assert.deepEqual(this.changedAttributes(), {x: true, y: true});
+          assert.equal(model.previous('x'), undefined);
+          model.set({z: true});
+          break;
+        case 2:
+          assert.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
+          assert.equal(model.previous('y'), undefined);
+          break;
+        default:
+          assert.ok(false);
+      }
+    });
+    model.set({x: true});
+  });
+
+  QUnit.test('nested `change` with silent', function(assert) {
+    assert.expect(3);
+    var count = 0;
+    var model = new Backbone.Model();
+    model.on('change:y', function() { assert.ok(false); });
+    model.on('change', function() {
+      switch (count++) {
+        case 0:
+          assert.deepEqual(this.changedAttributes(), {x: true});
+          model.set({y: true}, {silent: true});
+          model.set({z: true});
+          break;
+        case 1:
+          assert.deepEqual(this.changedAttributes(), {x: true, y: true, z: true});
+          break;
+        case 2:
+          assert.deepEqual(this.changedAttributes(), {z: false});
+          break;
+        default:
+          assert.ok(false);
+      }
+    });
+    model.set({x: true});
+    model.set({z: false});
+  });
+
+  QUnit.test('nested `change:attr` with silent', function(assert) {
+    assert.expect(0);
+    var model = new Backbone.Model();
+    model.on('change:y', function(){ assert.ok(false); });
+    model.on('change', function() {
+      model.set({y: true}, {silent: true});
+      model.set({z: true});
+    });
+    model.set({x: true});
+  });
+
+  QUnit.test('multiple nested changes with silent', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.on('change:x', function() {
+      model.set({y: 1}, {silent: true});
+      model.set({y: 2});
+    });
+    model.on('change:y', function(m, val) {
+      assert.equal(val, 2);
+    });
+    model.set({x: true});
+  });
+
+  QUnit.test('multiple nested changes with silent', function(assert) {
+    assert.expect(1);
+    var changes = [];
+    var model = new Backbone.Model();
+    model.on('change:b', function(m, val) { changes.push(val); });
+    model.on('change', function() {
+      model.set({b: 1});
+    });
+    model.set({b: 0});
+    assert.deepEqual(changes, [0, 1]);
+  });
+
+  QUnit.test('basic silent change semantics', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model;
+    model.set({x: 1});
+    model.on('change', function(){ assert.ok(true); });
+    model.set({x: 2}, {silent: true});
+    model.set({x: 1});
+  });
+
+  QUnit.test('nested set multiple times', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.on('change:b', function() {
+      assert.ok(true);
+    });
+    model.on('change:a', function() {
+      model.set({b: true});
+      model.set({b: true});
+    });
+    model.set({a: true});
+  });
+
+  QUnit.test('#1122 - clear does not alter options.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    var options = {};
+    model.clear(options);
+    assert.ok(!options.unset);
+  });
+
+  QUnit.test('#1122 - unset does not alter options.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    var options = {};
+    model.unset('x', options);
+    assert.ok(!options.unset);
+  });
+
+  QUnit.test('#1355 - `options` is passed to success callbacks', function(assert) {
+    assert.expect(3);
+    var model = new Backbone.Model();
+    var opts = {
+      success: function( m, resp, options ) {
+        assert.ok(options);
+      }
+    };
+    model.sync = function(method, m, options) {
+      options.success();
+    };
+    model.save({id: 1}, opts);
+    model.fetch(opts);
+    model.destroy(opts);
+  });
+
+  QUnit.test("#1412 - Trigger 'sync' event.", function(assert) {
+    assert.expect(3);
+    var model = new Backbone.Model({id: 1});
+    model.sync = function(method, m, options) { options.success(); };
+    model.on('sync', function(){ assert.ok(true); });
+    model.fetch();
+    model.save();
+    model.destroy();
+  });
+
+  QUnit.test('#1365 - Destroy: New models execute success callback.', function(assert) {
+    var done = assert.async();
+    assert.expect(2);
+    new Backbone.Model()
+    .on('sync', function() { assert.ok(false); })
+    .on('destroy', function(){ assert.ok(true); })
+    .destroy({success: function(){
+      assert.ok(true);
+      done();
+    }});
+  });
+
+  QUnit.test('#1433 - Save: An invalid model cannot be persisted.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model;
+    model.validate = function(){ return 'invalid'; };
+    model.sync = function(){ assert.ok(false); };
+    assert.strictEqual(model.save(), false);
+  });
+
+  QUnit.test("#1377 - Save without attrs triggers 'error'.", function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      url: '/test/',
+      sync: function(method, m, options){ options.success(); },
+      validate: function(){ return 'invalid'; }
+    });
+    var model = new Model({id: 1});
+    model.on('invalid', function(){ assert.ok(true); });
+    model.save();
+  });
+
+  QUnit.test('#1545 - `undefined` can be passed to a model constructor without coersion', function(assert) {
+    var Model = Backbone.Model.extend({
+      defaults: {one: 1},
+      initialize: function(attrs, opts) {
+        assert.equal(attrs, undefined);
+      }
+    });
+    var emptyattrs = new Model();
+    var undefinedattrs = new Model(undefined);
+  });
+
+  QUnit.test('#1478 - Model `save` does not trigger change on unchanged attributes', function(assert) {
+    var done = assert.async();
+    assert.expect(0);
+    var Model = Backbone.Model.extend({
+      sync: function(method, m, options) {
+        setTimeout(function(){
+          options.success();
+          done();
+        }, 0);
+      }
+    });
+    new Model({x: true})
+    .on('change:x', function(){ assert.ok(false); })
+    .save(null, {wait: true});
+  });
+
+  QUnit.test('#1664 - Changing from one value, silently to another, back to original triggers a change.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model({x: 1});
+    model.on('change:x', function() { assert.ok(true); });
+    model.set({x: 2}, {silent: true});
+    model.set({x: 3}, {silent: true});
+    model.set({x: 1});
+  });
+
+  QUnit.test('#1664 - multiple silent changes nested inside a change event', function(assert) {
+    assert.expect(2);
+    var changes = [];
+    var model = new Backbone.Model();
+    model.on('change', function() {
+      model.set({a: 'c'}, {silent: true});
+      model.set({b: 2}, {silent: true});
+      model.unset('c', {silent: true});
+    });
+    model.on('change:a change:b change:c', function(m, val) { changes.push(val); });
+    model.set({a: 'a', b: 1, c: 'item'});
+    assert.deepEqual(changes, ['a', 1, 'item']);
+    assert.deepEqual(model.attributes, {a: 'c', b: 2});
+  });
+
+  QUnit.test('#1791 - `attributes` is available for `parse`', function(assert) {
+    var Model = Backbone.Model.extend({
+      parse: function() { this.has('a'); } // shouldn't throw an error
+    });
+    var model = new Model(null, {parse: true});
+    assert.expect(0);
+  });
+
+  QUnit.test('silent changes in last `change` event back to original triggers change', function(assert) {
+    assert.expect(2);
+    var changes = [];
+    var model = new Backbone.Model();
+    model.on('change:a change:b change:c', function(m, val) { changes.push(val); });
+    model.on('change', function() {
+      model.set({a: 'c'}, {silent: true});
+    });
+    model.set({a: 'a'});
+    assert.deepEqual(changes, ['a']);
+    model.set({a: 'a'});
+    assert.deepEqual(changes, ['a', 'a']);
+  });
+
+  QUnit.test('#1943 change calculations should use _.isEqual', function(assert) {
+    var model = new Backbone.Model({a: {key: 'value'}});
+    model.set('a', {key: 'value'}, {silent: true});
+    assert.equal(model.changedAttributes(), false);
+  });
+
+  QUnit.test('#1964 - final `change` event is always fired, regardless of interim changes', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.on('change:property', function() {
+      model.set('property', 'bar');
+    });
+    model.on('change', function() {
+      assert.ok(true);
+    });
+    model.set('property', 'foo');
+  });
+
+  QUnit.test('isValid', function(assert) {
+    var model = new Backbone.Model({valid: true});
+    model.validate = function(attrs) {
+      if (!attrs.valid) return 'invalid';
+    };
+    assert.equal(model.isValid(), true);
+    assert.equal(model.set({valid: false}, {validate: true}), false);
+    assert.equal(model.isValid(), true);
+    model.set({valid: false});
+    assert.equal(model.isValid(), false);
+    assert.ok(!model.set('valid', false, {validate: true}));
+  });
+
+  QUnit.test('#1179 - isValid returns true in the absence of validate.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.validate = null;
+    assert.ok(model.isValid());
+  });
+
+  QUnit.test('#1961 - Creating a model with {validate:true} will call validate and use the error callback', function(assert) {
+    var Model = Backbone.Model.extend({
+      validate: function(attrs) {
+        if (attrs.id === 1) return "This shouldn't happen";
+      }
+    });
+    var model = new Model({id: 1}, {validate: true});
+    assert.equal(model.validationError, "This shouldn't happen");
+  });
+
+  QUnit.test('toJSON receives attrs during save(..., {wait: true})', function(assert) {
+    assert.expect(1);
+    var Model = Backbone.Model.extend({
+      url: '/test',
+      toJSON: function() {
+        assert.strictEqual(this.attributes.x, 1);
+        return _.clone(this.attributes);
+      }
+    });
+    var model = new Model;
+    model.save({x: 1}, {wait: true});
+  });
+
+  QUnit.test('#2034 - nested set with silent only triggers one change', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model();
+    model.on('change', function() {
+      model.set({b: true}, {silent: true});
+      assert.ok(true);
+    });
+    model.set({a: true});
+  });
+
+  QUnit.test('#3778 - id will only be updated if it is set', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model({id: 1});
+    model.id = 2;
+    model.set({foo: 'bar'});
+    assert.equal(model.id, 2);
+    model.set({id: 3});
+    assert.equal(model.id, 3);
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/noconflict.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/noconflict.js
new file mode 100644
index 0000000..9968f68
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/noconflict.js
@@ -0,0 +1,13 @@
+(function() {
+
+  QUnit.module('Backbone.noConflict');
+
+  QUnit.test('noConflict', function(assert) {
+    assert.expect(2);
+    var noconflictBackbone = Backbone.noConflict();
+    assert.equal(window.Backbone, undefined, 'Returned window.Backbone');
+    window.Backbone = noconflictBackbone;
+    assert.equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/router.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/router.js
new file mode 100644
index 0000000..13110c4
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/router.js
@@ -0,0 +1,1062 @@
+(function() {
+
+  var router = null;
+  var location = null;
+  var lastRoute = null;
+  var lastArgs = [];
+
+  var onRoute = function(routerParam, route, args) {
+    lastRoute = route;
+    lastArgs = args;
+  };
+
+  var Location = function(href) {
+    this.replace(href);
+  };
+
+  _.extend(Location.prototype, {
+
+    parser: document.createElement('a'),
+
+    replace: function(href) {
+      this.parser.href = href;
+      _.extend(this, _.pick(this.parser,
+        'href',
+        'hash',
+        'host',
+        'search',
+        'fragment',
+        'pathname',
+        'protocol'
+      ));
+      // In IE, anchor.pathname does not contain a leading slash though
+      // window.location.pathname does.
+      if (!/^\//.test(this.pathname)) this.pathname = '/' + this.pathname;
+    },
+
+    toString: function() {
+      return this.href;
+    }
+
+  });
+
+  QUnit.module('Backbone.Router', {
+
+    setup: function() {
+      location = new Location('http://example.com');
+      Backbone.history = _.extend(new Backbone.History, {location: location});
+      router = new Router({testing: 101});
+      Backbone.history.interval = 9;
+      Backbone.history.start({pushState: false});
+      lastRoute = null;
+      lastArgs = [];
+      Backbone.history.on('route', onRoute);
+    },
+
+    teardown: function() {
+      Backbone.history.stop();
+      Backbone.history.off('route', onRoute);
+    }
+
+  });
+
+  var ExternalObject = {
+    value: 'unset',
+
+    routingFunction: function(value) {
+      this.value = value;
+    }
+  };
+  ExternalObject.routingFunction = _.bind(ExternalObject.routingFunction, ExternalObject);
+
+  var Router = Backbone.Router.extend({
+
+    count: 0,
+
+    routes: {
+      'noCallback': 'noCallback',
+      'counter': 'counter',
+      'search/:query': 'search',
+      'search/:query/p:page': 'search',
+      'charñ': 'charUTF',
+      'char%C3%B1': 'charEscaped',
+      'contacts': 'contacts',
+      'contacts/new': 'newContact',
+      'contacts/:id': 'loadContact',
+      'route-event/:arg': 'routeEvent',
+      'optional(/:item)': 'optionalItem',
+      'named/optional/(y:z)': 'namedOptional',
+      'splat/*args/end': 'splat',
+      ':repo/compare/*from...*to': 'github',
+      'decode/:named/*splat': 'decode',
+      '*first/complex-*part/*rest': 'complex',
+      'query/:entity': 'query',
+      'function/:value': ExternalObject.routingFunction,
+      '*anything': 'anything'
+    },
+
+    initialize: function(options) {
+      this.testing = options.testing;
+      this.route('implicit', 'implicit');
+    },
+
+    counter: function() {
+      this.count++;
+    },
+
+    implicit: function() {
+      this.count++;
+    },
+
+    search: function(query, page) {
+      this.query = query;
+      this.page = page;
+    },
+
+    charUTF: function() {
+      this.charType = 'UTF';
+    },
+
+    charEscaped: function() {
+      this.charType = 'escaped';
+    },
+
+    contacts: function(){
+      this.contact = 'index';
+    },
+
+    newContact: function(){
+      this.contact = 'new';
+    },
+
+    loadContact: function(){
+      this.contact = 'load';
+    },
+
+    optionalItem: function(arg){
+      this.arg = arg !== void 0 ? arg : null;
+    },
+
+    splat: function(args) {
+      this.args = args;
+    },
+
+    github: function(repo, from, to) {
+      this.repo = repo;
+      this.from = from;
+      this.to = to;
+    },
+
+    complex: function(first, part, rest) {
+      this.first = first;
+      this.part = part;
+      this.rest = rest;
+    },
+
+    query: function(entity, args) {
+      this.entity    = entity;
+      this.queryArgs = args;
+    },
+
+    anything: function(whatever) {
+      this.anything = whatever;
+    },
+
+    namedOptional: function(z) {
+      this.z = z;
+    },
+
+    decode: function(named, path) {
+      this.named = named;
+      this.path = path;
+    },
+
+    routeEvent: function(arg) {
+    }
+
+  });
+
+  QUnit.test('initialize', function(assert) {
+    assert.expect(1);
+    assert.equal(router.testing, 101);
+  });
+
+  QUnit.test('routes (simple)', function(assert) {
+    assert.expect(4);
+    location.replace('http://example.com#search/news');
+    Backbone.history.checkUrl();
+    assert.equal(router.query, 'news');
+    assert.equal(router.page, void 0);
+    assert.equal(lastRoute, 'search');
+    assert.equal(lastArgs[0], 'news');
+  });
+
+  QUnit.test('routes (simple, but unicode)', function(assert) {
+    assert.expect(4);
+    location.replace('http://example.com#search/тест');
+    Backbone.history.checkUrl();
+    assert.equal(router.query, 'тест');
+    assert.equal(router.page, void 0);
+    assert.equal(lastRoute, 'search');
+    assert.equal(lastArgs[0], 'тест');
+  });
+
+  QUnit.test('routes (two part)', function(assert) {
+    assert.expect(2);
+    location.replace('http://example.com#search/nyc/p10');
+    Backbone.history.checkUrl();
+    assert.equal(router.query, 'nyc');
+    assert.equal(router.page, '10');
+  });
+
+  QUnit.test('routes via navigate', function(assert) {
+    assert.expect(2);
+    Backbone.history.navigate('search/manhattan/p20', {trigger: true});
+    assert.equal(router.query, 'manhattan');
+    assert.equal(router.page, '20');
+  });
+
+  QUnit.test('routes via navigate with params', function(assert) {
+    assert.expect(1);
+    Backbone.history.navigate('query/test?a=b', {trigger: true});
+    assert.equal(router.queryArgs, 'a=b');
+  });
+
+  QUnit.test('routes via navigate for backwards-compatibility', function(assert) {
+    assert.expect(2);
+    Backbone.history.navigate('search/manhattan/p20', true);
+    assert.equal(router.query, 'manhattan');
+    assert.equal(router.page, '20');
+  });
+
+  QUnit.test('reports matched route via nagivate', function(assert) {
+    assert.expect(1);
+    assert.ok(Backbone.history.navigate('search/manhattan/p20', true));
+  });
+
+  QUnit.test('route precedence via navigate', function(assert){
+    assert.expect(6);
+    // check both 0.9.x and backwards-compatibility options
+    _.each([{trigger: true}, true], function( options ){
+      Backbone.history.navigate('contacts', options);
+      assert.equal(router.contact, 'index');
+      Backbone.history.navigate('contacts/new', options);
+      assert.equal(router.contact, 'new');
+      Backbone.history.navigate('contacts/foo', options);
+      assert.equal(router.contact, 'load');
+    });
+  });
+
+  QUnit.test('loadUrl is not called for identical routes.', function(assert) {
+    assert.expect(0);
+    Backbone.history.loadUrl = function(){ assert.ok(false); };
+    location.replace('http://example.com#route');
+    Backbone.history.navigate('route');
+    Backbone.history.navigate('/route');
+    Backbone.history.navigate('/route');
+  });
+
+  QUnit.test('use implicit callback if none provided', function(assert) {
+    assert.expect(1);
+    router.count = 0;
+    router.navigate('implicit', {trigger: true});
+    assert.equal(router.count, 1);
+  });
+
+  QUnit.test('routes via navigate with {replace: true}', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com#start_here');
+    Backbone.history.checkUrl();
+    location.replace = function(href) {
+      assert.strictEqual(href, new Location('http://example.com#end_here').href);
+    };
+    Backbone.history.navigate('end_here', {replace: true});
+  });
+
+  QUnit.test('routes (splats)', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
+    Backbone.history.checkUrl();
+    assert.equal(router.args, 'long-list/of/splatted_99args');
+  });
+
+  QUnit.test('routes (github)', function(assert) {
+    assert.expect(3);
+    location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');
+    Backbone.history.checkUrl();
+    assert.equal(router.repo, 'backbone');
+    assert.equal(router.from, '1.0');
+    assert.equal(router.to, 'braddunbar:with/slash');
+  });
+
+  QUnit.test('routes (optional)', function(assert) {
+    assert.expect(2);
+    location.replace('http://example.com#optional');
+    Backbone.history.checkUrl();
+    assert.ok(!router.arg);
+    location.replace('http://example.com#optional/thing');
+    Backbone.history.checkUrl();
+    assert.equal(router.arg, 'thing');
+  });
+
+  QUnit.test('routes (complex)', function(assert) {
+    assert.expect(3);
+    location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
+    Backbone.history.checkUrl();
+    assert.equal(router.first, 'one/two/three');
+    assert.equal(router.part, 'part');
+    assert.equal(router.rest, 'four/five/six/seven');
+  });
+
+  QUnit.test('routes (query)', function(assert) {
+    assert.expect(5);
+    location.replace('http://example.com#query/mandel?a=b&c=d');
+    Backbone.history.checkUrl();
+    assert.equal(router.entity, 'mandel');
+    assert.equal(router.queryArgs, 'a=b&c=d');
+    assert.equal(lastRoute, 'query');
+    assert.equal(lastArgs[0], 'mandel');
+    assert.equal(lastArgs[1], 'a=b&c=d');
+  });
+
+  QUnit.test('routes (anything)', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com#doesnt-match-a-route');
+    Backbone.history.checkUrl();
+    assert.equal(router.anything, 'doesnt-match-a-route');
+  });
+
+  QUnit.test('routes (function)', function(assert) {
+    assert.expect(3);
+    router.on('route', function(name) {
+      assert.ok(name === '');
+    });
+    assert.equal(ExternalObject.value, 'unset');
+    location.replace('http://example.com#function/set');
+    Backbone.history.checkUrl();
+    assert.equal(ExternalObject.value, 'set');
+  });
+
+  QUnit.test('Decode named parameters, not splats.', function(assert) {
+    assert.expect(2);
+    location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');
+    Backbone.history.checkUrl();
+    assert.strictEqual(router.named, 'a/b');
+    assert.strictEqual(router.path, 'c/d/e');
+  });
+
+  QUnit.test("fires event when router doesn't have callback on it", function(assert) {
+    assert.expect(1);
+    router.on('route:noCallback', function(){ assert.ok(true); });
+    location.replace('http://example.com#noCallback');
+    Backbone.history.checkUrl();
+  });
+
+  QUnit.test('No events are triggered if #execute returns false.', function(assert) {
+    assert.expect(1);
+    var MyRouter = Backbone.Router.extend({
+
+      routes: {
+        foo: function() {
+          assert.ok(true);
+        }
+      },
+
+      execute: function(callback, args) {
+        callback.apply(this, args);
+        return false;
+      }
+
+    });
+
+    var myRouter = new MyRouter;
+
+    myRouter.on('route route:foo', function() {
+      assert.ok(false);
+    });
+
+    Backbone.history.on('route', function() {
+      assert.ok(false);
+    });
+
+    location.replace('http://example.com#foo');
+    Backbone.history.checkUrl();
+  });
+
+  QUnit.test('#933, #908 - leading slash', function(assert) {
+    assert.expect(2);
+    location.replace('http://example.com/root/foo');
+
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({root: '/root', hashChange: false, silent: true});
+    assert.strictEqual(Backbone.history.getFragment(), 'foo');
+
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({root: '/root/', hashChange: false, silent: true});
+    assert.strictEqual(Backbone.history.getFragment(), 'foo');
+  });
+
+  QUnit.test('#967 - Route callback gets passed encoded values.', function(assert) {
+    assert.expect(3);
+    var route = 'has%2Fslash/complex-has%23hash/has%20space';
+    Backbone.history.navigate(route, {trigger: true});
+    assert.strictEqual(router.first, 'has/slash');
+    assert.strictEqual(router.part, 'has#hash');
+    assert.strictEqual(router.rest, 'has space');
+  });
+
+  QUnit.test('correctly handles URLs with % (#868)', function(assert) {
+    assert.expect(3);
+    location.replace('http://example.com#search/fat%3A1.5%25');
+    Backbone.history.checkUrl();
+    location.replace('http://example.com#search/fat');
+    Backbone.history.checkUrl();
+    assert.equal(router.query, 'fat');
+    assert.equal(router.page, void 0);
+    assert.equal(lastRoute, 'search');
+  });
+
+  QUnit.test('#2666 - Hashes with UTF8 in them.', function(assert) {
+    assert.expect(2);
+    Backbone.history.navigate('charñ', {trigger: true});
+    assert.equal(router.charType, 'UTF');
+    Backbone.history.navigate('char%C3%B1', {trigger: true});
+    assert.equal(router.charType, 'UTF');
+  });
+
+  QUnit.test('#1185 - Use pathname when hashChange is not wanted.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/path/name#hash');
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({hashChange: false});
+    var fragment = Backbone.history.getFragment();
+    assert.strictEqual(fragment, location.pathname.replace(/^\//, ''));
+  });
+
+  QUnit.test('#1206 - Strip leading slash before location.assign.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root/');
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({hashChange: false, root: '/root/'});
+    location.assign = function(pathname) {
+      assert.strictEqual(pathname, '/root/fragment');
+    };
+    Backbone.history.navigate('/fragment');
+  });
+
+  QUnit.test('#1387 - Root fragment without trailing slash.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root');
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({hashChange: false, root: '/root/', silent: true});
+    assert.strictEqual(Backbone.history.getFragment(), '');
+  });
+
+  QUnit.test('#1366 - History does not prepend root to fragment.', function(assert) {
+    assert.expect(2);
+    Backbone.history.stop();
+    location.replace('http://example.com/root/');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url) {
+          assert.strictEqual(url, '/root/x');
+        }
+      }
+    });
+    Backbone.history.start({
+      root: '/root/',
+      pushState: true,
+      hashChange: false
+    });
+    Backbone.history.navigate('x');
+    assert.strictEqual(Backbone.history.fragment, 'x');
+  });
+
+  QUnit.test('Normalize root.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url) {
+          assert.strictEqual(url, '/root/fragment');
+        }
+      }
+    });
+    Backbone.history.start({
+      pushState: true,
+      root: '/root',
+      hashChange: false
+    });
+    Backbone.history.navigate('fragment');
+  });
+
+  QUnit.test('Normalize root.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root#fragment');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url) {},
+        replaceState: function(state, title, url) {
+          assert.strictEqual(url, '/root/fragment');
+        }
+      }
+    });
+    Backbone.history.start({
+      pushState: true,
+      root: '/root'
+    });
+  });
+
+  QUnit.test('Normalize root.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root');
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.loadUrl = function() { assert.ok(true); };
+    Backbone.history.start({
+      pushState: true,
+      root: '/root'
+    });
+  });
+
+  QUnit.test('Normalize root - leading slash.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){},
+        replaceState: function(){}
+      }
+    });
+    Backbone.history.start({root: 'root'});
+    assert.strictEqual(Backbone.history.root, '/root/');
+  });
+
+  QUnit.test('Transition from hashChange to pushState.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root#x/y');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){},
+        replaceState: function(state, title, url){
+          assert.strictEqual(url, '/root/x/y');
+        }
+      }
+    });
+    Backbone.history.start({
+      root: 'root',
+      pushState: true
+    });
+  });
+
+  QUnit.test('#1619: Router: Normalize empty root', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){},
+        replaceState: function(){}
+      }
+    });
+    Backbone.history.start({root: ''});
+    assert.strictEqual(Backbone.history.root, '/');
+  });
+
+  QUnit.test('#1619: Router: nagivate with empty root', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url) {
+          assert.strictEqual(url, '/fragment');
+        }
+      }
+    });
+    Backbone.history.start({
+      pushState: true,
+      root: '',
+      hashChange: false
+    });
+    Backbone.history.navigate('fragment');
+  });
+
+  QUnit.test('Transition from pushState to hashChange.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root/x/y?a=b');
+    location.replace = function(url) {
+      assert.strictEqual(url, '/root#x/y?a=b');
+    };
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: null,
+        replaceState: null
+      }
+    });
+    Backbone.history.start({
+      root: 'root',
+      pushState: true
+    });
+  });
+
+  QUnit.test('#1695 - hashChange to pushState with search.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root#x/y?a=b');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){},
+        replaceState: function(state, title, url){
+          assert.strictEqual(url, '/root/x/y?a=b');
+        }
+      }
+    });
+    Backbone.history.start({
+      root: 'root',
+      pushState: true
+    });
+  });
+
+  QUnit.test('#1746 - Router allows empty route.', function(assert) {
+    assert.expect(1);
+    var MyRouter = Backbone.Router.extend({
+      routes: {'': 'empty'},
+      empty: function(){},
+      route: function(route){
+        assert.strictEqual(route, '');
+      }
+    });
+    new MyRouter;
+  });
+
+  QUnit.test('#1794 - Trailing space in fragments.', function(assert) {
+    assert.expect(1);
+    var history = new Backbone.History;
+    assert.strictEqual(history.getFragment('fragment   '), 'fragment');
+  });
+
+  QUnit.test('#1820 - Leading slash and trailing space.', 1, function(assert) {
+    var history = new Backbone.History;
+    assert.strictEqual(history.getFragment('/fragment '), 'fragment');
+  });
+
+  QUnit.test('#1980 - Optional parameters.', function(assert) {
+    assert.expect(2);
+    location.replace('http://example.com#named/optional/y');
+    Backbone.history.checkUrl();
+    assert.strictEqual(router.z, undefined);
+    location.replace('http://example.com#named/optional/y123');
+    Backbone.history.checkUrl();
+    assert.strictEqual(router.z, '123');
+  });
+
+  QUnit.test("#2062 - Trigger 'route' event on router instance.", function(assert) {
+    assert.expect(2);
+    router.on('route', function(name, args) {
+      assert.strictEqual(name, 'routeEvent');
+      assert.deepEqual(args, ['x', null]);
+    });
+    location.replace('http://example.com#route-event/x');
+    Backbone.history.checkUrl();
+  });
+
+  QUnit.test('#2255 - Extend routes by making routes a function.', function(assert) {
+    assert.expect(1);
+    var RouterBase = Backbone.Router.extend({
+      routes: function() {
+        return {
+          home: 'root',
+          index: 'index.html'
+        };
+      }
+    });
+
+    var RouterExtended = RouterBase.extend({
+      routes: function() {
+        var _super = RouterExtended.__super__.routes;
+        return _.extend(_super(), {show: 'show', search: 'search'});
+      }
+    });
+
+    var myRouter = new RouterExtended();
+    assert.deepEqual({home: 'root', index: 'index.html', show: 'show', search: 'search'}, myRouter.routes);
+  });
+
+  QUnit.test('#2538 - hashChange to pushState only if both requested.', function(assert) {
+    assert.expect(0);
+    Backbone.history.stop();
+    location.replace('http://example.com/root?a=b#x/y');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){},
+        replaceState: function(){ assert.ok(false); }
+      }
+    });
+    Backbone.history.start({
+      root: 'root',
+      pushState: true,
+      hashChange: false
+    });
+  });
+
+  QUnit.test('No hash fallback.', function(assert) {
+    assert.expect(0);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){},
+        replaceState: function(){}
+      }
+    });
+
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        hash: function() { assert.ok(false); }
+      }
+    });
+    var myRouter = new MyRouter;
+
+    location.replace('http://example.com/');
+    Backbone.history.start({
+      pushState: true,
+      hashChange: false
+    });
+    location.replace('http://example.com/nomatch#hash');
+    Backbone.history.checkUrl();
+  });
+
+  QUnit.test('#2656 - No trailing slash on root.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url){
+          assert.strictEqual(url, '/root');
+        }
+      }
+    });
+    location.replace('http://example.com/root/path');
+    Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
+    Backbone.history.navigate('');
+  });
+
+  QUnit.test('#2656 - No trailing slash on root.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url) {
+          assert.strictEqual(url, '/');
+        }
+      }
+    });
+    location.replace('http://example.com/path');
+    Backbone.history.start({pushState: true, hashChange: false});
+    Backbone.history.navigate('');
+  });
+
+  QUnit.test('#2656 - No trailing slash on root.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url){
+          assert.strictEqual(url, '/root?x=1');
+        }
+      }
+    });
+    location.replace('http://example.com/root/path');
+    Backbone.history.start({pushState: true, hashChange: false, root: 'root'});
+    Backbone.history.navigate('?x=1');
+  });
+
+  QUnit.test('#2765 - Fragment matching sans query/hash.', function(assert) {
+    assert.expect(2);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(state, title, url) {
+          assert.strictEqual(url, '/path?query#hash');
+        }
+      }
+    });
+
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        path: function() { assert.ok(true); }
+      }
+    });
+    var myRouter = new MyRouter;
+
+    location.replace('http://example.com/');
+    Backbone.history.start({pushState: true, hashChange: false});
+    Backbone.history.navigate('path?query#hash', true);
+  });
+
+  QUnit.test('Do not decode the search params.', function(assert) {
+    assert.expect(1);
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        path: function(params){
+          assert.strictEqual(params, 'x=y%3Fz');
+        }
+      }
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.navigate('path?x=y%3Fz', true);
+  });
+
+  QUnit.test('Navigate to a hash url.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({pushState: true});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        path: function(params) {
+          assert.strictEqual(params, 'x=y');
+        }
+      }
+    });
+    var myRouter = new MyRouter;
+    location.replace('http://example.com/path?x=y#hash');
+    Backbone.history.checkUrl();
+  });
+
+  QUnit.test('#navigate to a hash url.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    Backbone.history.start({pushState: true});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        path: function(params) {
+          assert.strictEqual(params, 'x=y');
+        }
+      }
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.navigate('path?x=y#hash', true);
+  });
+
+  QUnit.test('unicode pathname', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com/myyjä');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        myyjä: function() {
+          assert.ok(true);
+        }
+      }
+    });
+    new MyRouter;
+    Backbone.history.start({pushState: true});
+  });
+
+  QUnit.test('unicode pathname with % in a parameter', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com/myyjä/foo%20%25%3F%2f%40%25%20bar');
+    location.pathname = '/myyj%C3%A4/foo%20%25%3F%2f%40%25%20bar';
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        'myyjä/:query': function(query) {
+          assert.strictEqual(query, 'foo %?/@% bar');
+        }
+      }
+    });
+    new MyRouter;
+    Backbone.history.start({pushState: true});
+  });
+
+  QUnit.test('newline in route', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com/stuff%0Anonsense?param=foo%0Abar');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        'stuff\nnonsense': function() {
+          assert.ok(true);
+        }
+      }
+    });
+    new MyRouter;
+    Backbone.history.start({pushState: true});
+  });
+
+  QUnit.test('Router#execute receives callback, args, name.', function(assert) {
+    assert.expect(3);
+    location.replace('http://example.com#foo/123/bar?x=y');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {'foo/:id/bar': 'foo'},
+      foo: function(){},
+      execute: function(callback, args, name) {
+        assert.strictEqual(callback, this.foo);
+        assert.deepEqual(args, ['123', 'x=y']);
+        assert.strictEqual(name, 'foo');
+      }
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.start();
+  });
+
+  QUnit.test('pushState to hashChange with only search params.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com?a=b');
+    location.replace = function(url) {
+      assert.strictEqual(url, '/#?a=b');
+    };
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: null
+    });
+    Backbone.history.start({pushState: true});
+  });
+
+  QUnit.test('#3123 - History#navigate decodes before comparison.', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/shop/search?keyword=short%20dress');
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: function(){ assert.ok(false); },
+        replaceState: function(){ assert.ok(false); }
+      }
+    });
+    Backbone.history.start({pushState: true});
+    Backbone.history.navigate('shop/search?keyword=short%20dress', true);
+    assert.strictEqual(Backbone.history.fragment, 'shop/search?keyword=short dress');
+  });
+
+  QUnit.test('#3175 - Urls in the params', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com#login?a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var myRouter = new Backbone.Router;
+    myRouter.route('login', function(params) {
+      assert.strictEqual(params, 'a=value&backUrl=https%3A%2F%2Fwww.msn.com%2Fidp%2Fidpdemo%3Fspid%3Dspdemo%26target%3Db');
+    });
+    Backbone.history.start();
+  });
+
+  QUnit.test('#3358 - pushState to hashChange transition with search params', function(assert) {
+    assert.expect(1);
+    Backbone.history.stop();
+    location.replace('http://example.com/root?foo=bar');
+    location.replace = function(url) {
+      assert.strictEqual(url, '/root#?foo=bar');
+    };
+    Backbone.history = _.extend(new Backbone.History, {
+      location: location,
+      history: {
+        pushState: undefined,
+        replaceState: undefined
+      }
+    });
+    Backbone.history.start({root: '/root', pushState: true});
+  });
+
+  QUnit.test("Paths that don't match the root should not match no root", function(assert) {
+    assert.expect(0);
+    location.replace('http://example.com/foo');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        foo: function(){
+          assert.ok(false, 'should not match unless root matches');
+        }
+      }
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.start({root: 'root', pushState: true});
+  });
+
+  QUnit.test("Paths that don't match the root should not match roots of the same length", function(assert) {
+    assert.expect(0);
+    location.replace('http://example.com/xxxx/foo');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {
+        foo: function(){
+          assert.ok(false, 'should not match unless root matches');
+        }
+      }
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.start({root: 'root', pushState: true});
+  });
+
+  QUnit.test('roots with regex characters', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com/x+y.z/foo');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {foo: function(){ assert.ok(true); }}
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.start({root: 'x+y.z', pushState: true});
+  });
+
+  QUnit.test('roots with unicode characters', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com/®ooτ/foo');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {foo: function(){ assert.ok(true); }}
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.start({root: '®ooτ', pushState: true});
+  });
+
+  QUnit.test('roots without slash', function(assert) {
+    assert.expect(1);
+    location.replace('http://example.com/®ooτ');
+    Backbone.history.stop();
+    Backbone.history = _.extend(new Backbone.History, {location: location});
+    var MyRouter = Backbone.Router.extend({
+      routes: {'': function(){ assert.ok(true); }}
+    });
+    var myRouter = new MyRouter;
+    Backbone.history.start({root: '®ooτ', pushState: true});
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/setup/dom-setup.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/setup/dom-setup.js
new file mode 100644
index 0000000..f224228
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/setup/dom-setup.js
@@ -0,0 +1,4 @@
+$('body').append(
+    '<div id="qunit"></div>' +
+    '<div id="qunit-fixture"></div>'
+);
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/setup/environment.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/setup/environment.js
new file mode 100644
index 0000000..c2441ac
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/setup/environment.js
@@ -0,0 +1,45 @@
+(function() {
+
+  var sync = Backbone.sync;
+  var ajax = Backbone.ajax;
+  var emulateHTTP = Backbone.emulateHTTP;
+  var emulateJSON = Backbone.emulateJSON;
+  var history = window.history;
+  var pushState = history.pushState;
+  var replaceState = history.replaceState;
+
+  QUnit.config.noglobals = true;
+
+  QUnit.testStart(function() {
+    var env = QUnit.config.current.testEnvironment;
+
+    // We never want to actually call these during tests.
+    history.pushState = history.replaceState = function(){};
+
+    // Capture ajax settings for comparison.
+    Backbone.ajax = function(settings) {
+      env.ajaxSettings = settings;
+    };
+
+    // Capture the arguments to Backbone.sync for comparison.
+    Backbone.sync = function(method, model, options) {
+      env.syncArgs = {
+        method: method,
+        model: model,
+        options: options
+      };
+      sync.apply(this, arguments);
+    };
+
+  });
+
+  QUnit.testDone(function() {
+    Backbone.sync = sync;
+    Backbone.ajax = ajax;
+    Backbone.emulateHTTP = emulateHTTP;
+    Backbone.emulateJSON = emulateJSON;
+    history.pushState = pushState;
+    history.replaceState = replaceState;
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/sync.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/sync.js
new file mode 100644
index 0000000..8813f15
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/sync.js
@@ -0,0 +1,239 @@
+(function() {
+
+  var Library = Backbone.Collection.extend({
+    url: function() { return '/library'; }
+  });
+  var library;
+
+  var attrs = {
+    title: 'The Tempest',
+    author: 'Bill Shakespeare',
+    length: 123
+  };
+
+  QUnit.module('Backbone.sync', {
+
+    beforeEach: function(assert) {
+      library = new Library;
+      library.create(attrs, {wait: false});
+    },
+
+    afterEach: function(assert) {
+      Backbone.emulateHTTP = false;
+    }
+
+  });
+
+  QUnit.test('read', function(assert) {
+    assert.expect(4);
+    library.fetch();
+    assert.equal(this.ajaxSettings.url, '/library');
+    assert.equal(this.ajaxSettings.type, 'GET');
+    assert.equal(this.ajaxSettings.dataType, 'json');
+    assert.ok(_.isEmpty(this.ajaxSettings.data));
+  });
+
+  QUnit.test('passing data', function(assert) {
+    assert.expect(3);
+    library.fetch({data: {a: 'a', one: 1}});
+    assert.equal(this.ajaxSettings.url, '/library');
+    assert.equal(this.ajaxSettings.data.a, 'a');
+    assert.equal(this.ajaxSettings.data.one, 1);
+  });
+
+  QUnit.test('create', function(assert) {
+    assert.expect(6);
+    assert.equal(this.ajaxSettings.url, '/library');
+    assert.equal(this.ajaxSettings.type, 'POST');
+    assert.equal(this.ajaxSettings.dataType, 'json');
+    var data = JSON.parse(this.ajaxSettings.data);
+    assert.equal(data.title, 'The Tempest');
+    assert.equal(data.author, 'Bill Shakespeare');
+    assert.equal(data.length, 123);
+  });
+
+  QUnit.test('update', function(assert) {
+    assert.expect(7);
+    library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
+    assert.equal(this.ajaxSettings.url, '/library/1-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'PUT');
+    assert.equal(this.ajaxSettings.dataType, 'json');
+    var data = JSON.parse(this.ajaxSettings.data);
+    assert.equal(data.id, '1-the-tempest');
+    assert.equal(data.title, 'The Tempest');
+    assert.equal(data.author, 'William Shakespeare');
+    assert.equal(data.length, 123);
+  });
+
+  QUnit.test('update with emulateHTTP and emulateJSON', function(assert) {
+    assert.expect(7);
+    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
+      emulateHTTP: true,
+      emulateJSON: true
+    });
+    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'POST');
+    assert.equal(this.ajaxSettings.dataType, 'json');
+    assert.equal(this.ajaxSettings.data._method, 'PUT');
+    var data = JSON.parse(this.ajaxSettings.data.model);
+    assert.equal(data.id, '2-the-tempest');
+    assert.equal(data.author, 'Tim Shakespeare');
+    assert.equal(data.length, 123);
+  });
+
+  QUnit.test('update with just emulateHTTP', function(assert) {
+    assert.expect(6);
+    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
+      emulateHTTP: true
+    });
+    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'POST');
+    assert.equal(this.ajaxSettings.contentType, 'application/json');
+    var data = JSON.parse(this.ajaxSettings.data);
+    assert.equal(data.id, '2-the-tempest');
+    assert.equal(data.author, 'Tim Shakespeare');
+    assert.equal(data.length, 123);
+  });
+
+  QUnit.test('update with just emulateJSON', function(assert) {
+    assert.expect(6);
+    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
+      emulateJSON: true
+    });
+    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'PUT');
+    assert.equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
+    var data = JSON.parse(this.ajaxSettings.data.model);
+    assert.equal(data.id, '2-the-tempest');
+    assert.equal(data.author, 'Tim Shakespeare');
+    assert.equal(data.length, 123);
+  });
+
+  QUnit.test('read model', function(assert) {
+    assert.expect(3);
+    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
+    library.first().fetch();
+    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'GET');
+    assert.ok(_.isEmpty(this.ajaxSettings.data));
+  });
+
+  QUnit.test('destroy', function(assert) {
+    assert.expect(3);
+    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
+    library.first().destroy({wait: true});
+    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'DELETE');
+    assert.equal(this.ajaxSettings.data, null);
+  });
+
+  QUnit.test('destroy with emulateHTTP', function(assert) {
+    assert.expect(3);
+    library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
+    library.first().destroy({
+      emulateHTTP: true,
+      emulateJSON: true
+    });
+    assert.equal(this.ajaxSettings.url, '/library/2-the-tempest');
+    assert.equal(this.ajaxSettings.type, 'POST');
+    assert.equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
+  });
+
+  QUnit.test('urlError', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model();
+    assert.raises(function() {
+      model.fetch();
+    });
+    model.fetch({url: '/one/two'});
+    assert.equal(this.ajaxSettings.url, '/one/two');
+  });
+
+  QUnit.test('#1052 - `options` is optional.', function(assert) {
+    assert.expect(0);
+    var model = new Backbone.Model();
+    model.url = '/test';
+    Backbone.sync('create', model);
+  });
+
+  QUnit.test('Backbone.ajax', function(assert) {
+    assert.expect(1);
+    Backbone.ajax = function(settings){
+      assert.strictEqual(settings.url, '/test');
+    };
+    var model = new Backbone.Model();
+    model.url = '/test';
+    Backbone.sync('create', model);
+  });
+
+  QUnit.test('Call provided error callback on error.', function(assert) {
+    assert.expect(1);
+    var model = new Backbone.Model;
+    model.url = '/test';
+    Backbone.sync('read', model, {
+      error: function() { assert.ok(true); }
+    });
+    this.ajaxSettings.error();
+  });
+
+  QUnit.test('Use Backbone.emulateHTTP as default.', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model;
+    model.url = '/test';
+
+    Backbone.emulateHTTP = true;
+    model.sync('create', model);
+    assert.strictEqual(this.ajaxSettings.emulateHTTP, true);
+
+    Backbone.emulateHTTP = false;
+    model.sync('create', model);
+    assert.strictEqual(this.ajaxSettings.emulateHTTP, false);
+  });
+
+  QUnit.test('Use Backbone.emulateJSON as default.', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model;
+    model.url = '/test';
+
+    Backbone.emulateJSON = true;
+    model.sync('create', model);
+    assert.strictEqual(this.ajaxSettings.emulateJSON, true);
+
+    Backbone.emulateJSON = false;
+    model.sync('create', model);
+    assert.strictEqual(this.ajaxSettings.emulateJSON, false);
+  });
+
+  QUnit.test('#1756 - Call user provided beforeSend function.', function(assert) {
+    assert.expect(4);
+    Backbone.emulateHTTP = true;
+    var model = new Backbone.Model;
+    model.url = '/test';
+    var xhr = {
+      setRequestHeader: function(header, value) {
+        assert.strictEqual(header, 'X-HTTP-Method-Override');
+        assert.strictEqual(value, 'DELETE');
+      }
+    };
+    model.sync('delete', model, {
+      beforeSend: function(_xhr) {
+        assert.ok(_xhr === xhr);
+        return false;
+      }
+    });
+    assert.strictEqual(this.ajaxSettings.beforeSend(xhr), false);
+  });
+
+  QUnit.test('#2928 - Pass along `textStatus` and `errorThrown`.', function(assert) {
+    assert.expect(2);
+    var model = new Backbone.Model;
+    model.url = '/test';
+    model.on('error', function(m, xhr, options) {
+      assert.strictEqual(options.textStatus, 'textStatus');
+      assert.strictEqual(options.errorThrown, 'errorThrown');
+    });
+    model.fetch();
+    this.ajaxSettings.error({}, 'textStatus', 'errorThrown');
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/view.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/view.js
new file mode 100644
index 0000000..faf3445
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/backbone/test/view.js
@@ -0,0 +1,495 @@
+(function() {
+
+  var view;
+
+  QUnit.module('Backbone.View', {
+
+    beforeEach: function(assert) {
+      $('#qunit-fixture').append(
+        '<div id="testElement"><h1>Test</h1></div>'
+      );
+
+      view = new Backbone.View({
+        id: 'test-view',
+        className: 'test-view',
+        other: 'non-special-option'
+      });
+    },
+
+    afterEach: function() {
+      $('#testElement').remove();
+      $('#test-view').remove();
+    }
+
+  });
+
+  QUnit.test('constructor', function(assert) {
+    assert.expect(3);
+    assert.equal(view.el.id, 'test-view');
+    assert.equal(view.el.className, 'test-view');
+    assert.equal(view.el.other, void 0);
+  });
+
+  QUnit.test('$', function(assert) {
+    assert.expect(2);
+    var myView = new Backbone.View;
+    myView.setElement('<p><a><b>test</b></a></p>');
+    var result = myView.$('a b');
+
+    assert.strictEqual(result[0].innerHTML, 'test');
+    assert.ok(result.length === +result.length);
+  });
+
+  QUnit.test('$el', function(assert) {
+    assert.expect(3);
+    var myView = new Backbone.View;
+    myView.setElement('<p><a><b>test</b></a></p>');
+    assert.strictEqual(myView.el.nodeType, 1);
+
+    assert.ok(myView.$el instanceof Backbone.$);
+    assert.strictEqual(myView.$el[0], myView.el);
+  });
+
+  QUnit.test('initialize', function(assert) {
+    assert.expect(1);
+    var View = Backbone.View.extend({
+      initialize: function() {
+        this.one = 1;
+      }
+    });
+
+    assert.strictEqual(new View().one, 1);
+  });
+
+  QUnit.test('render', function(assert) {
+    assert.expect(1);
+    var myView = new Backbone.View;
+    assert.equal(myView.render(), myView, '#render returns the view instance');
+  });
+
+  QUnit.test('delegateEvents', function(assert) {
+    assert.expect(6);
+    var counter1 = 0, counter2 = 0;
+
+    var myView = new Backbone.View({el: '#testElement'});
+    myView.increment = function(){ counter1++; };
+    myView.$el.on('click', function(){ counter2++; });
+
+    var events = {'click h1': 'increment'};
+
+    myView.delegateEvents(events);
+    myView.$('h1').trigger('click');
+    assert.equal(counter1, 1);
+    assert.equal(counter2, 1);
+
+    myView.$('h1').trigger('click');
+    assert.equal(counter1, 2);
+    assert.equal(counter2, 2);
+
+    myView.delegateEvents(events);
+    myView.$('h1').trigger('click');
+    assert.equal(counter1, 3);
+    assert.equal(counter2, 3);
+  });
+
+  QUnit.test('delegate', function(assert) {
+    assert.expect(3);
+    var myView = new Backbone.View({el: '#testElement'});
+    myView.delegate('click', 'h1', function() {
+      assert.ok(true);
+    });
+    myView.delegate('click', function() {
+      assert.ok(true);
+    });
+    myView.$('h1').trigger('click');
+
+    assert.equal(myView.delegate(), myView, '#delegate returns the view instance');
+  });
+
+  QUnit.test('delegateEvents allows functions for callbacks', function(assert) {
+    assert.expect(3);
+    var myView = new Backbone.View({el: '<p></p>'});
+    myView.counter = 0;
+
+    var events = {
+      click: function() {
+        this.counter++;
+      }
+    };
+
+    myView.delegateEvents(events);
+    myView.$el.trigger('click');
+    assert.equal(myView.counter, 1);
+
+    myView.$el.trigger('click');
+    assert.equal(myView.counter, 2);
+
+    myView.delegateEvents(events);
+    myView.$el.trigger('click');
+    assert.equal(myView.counter, 3);
+  });
+
+
+  QUnit.test('delegateEvents ignore undefined methods', function(assert) {
+    assert.expect(0);
+    var myView = new Backbone.View({el: '<p></p>'});
+    myView.delegateEvents({'click': 'undefinedMethod'});
+    myView.$el.trigger('click');
+  });
+
+  QUnit.test('undelegateEvents', function(assert) {
+    assert.expect(7);
+    var counter1 = 0, counter2 = 0;
+
+    var myView = new Backbone.View({el: '#testElement'});
+    myView.increment = function(){ counter1++; };
+    myView.$el.on('click', function(){ counter2++; });
+
+    var events = {'click h1': 'increment'};
+
+    myView.delegateEvents(events);
+    myView.$('h1').trigger('click');
+    assert.equal(counter1, 1);
+    assert.equal(counter2, 1);
+
+    myView.undelegateEvents();
+    myView.$('h1').trigger('click');
+    assert.equal(counter1, 1);
+    assert.equal(counter2, 2);
+
+    myView.delegateEvents(events);
+    myView.$('h1').trigger('click');
+    assert.equal(counter1, 2);
+    assert.equal(counter2, 3);
+
+    assert.equal(myView.undelegateEvents(), myView, '#undelegateEvents returns the view instance');
+  });
+
+  QUnit.test('undelegate', function(assert) {
+    assert.expect(1);
+    var myView = new Backbone.View({el: '#testElement'});
+    myView.delegate('click', function() { assert.ok(false); });
+    myView.delegate('click', 'h1', function() { assert.ok(false); });
+
+    myView.undelegate('click');
+
+    myView.$('h1').trigger('click');
+    myView.$el.trigger('click');
+
+    assert.equal(myView.undelegate(), myView, '#undelegate returns the view instance');
+  });
+
+  QUnit.test('undelegate with passed handler', function(assert) {
+    assert.expect(1);
+    var myView = new Backbone.View({el: '#testElement'});
+    var listener = function() { assert.ok(false); };
+    myView.delegate('click', listener);
+    myView.delegate('click', function() { assert.ok(true); });
+    myView.undelegate('click', listener);
+    myView.$el.trigger('click');
+  });
+
+  QUnit.test('undelegate with selector', function(assert) {
+    assert.expect(2);
+    var myView = new Backbone.View({el: '#testElement'});
+    myView.delegate('click', function() { assert.ok(true); });
+    myView.delegate('click', 'h1', function() { assert.ok(false); });
+    myView.undelegate('click', 'h1');
+    myView.$('h1').trigger('click');
+    myView.$el.trigger('click');
+  });
+
+  QUnit.test('undelegate with handler and selector', function(assert) {
+    assert.expect(2);
+    var myView = new Backbone.View({el: '#testElement'});
+    myView.delegate('click', function() { assert.ok(true); });
+    var handler = function(){ assert.ok(false); };
+    myView.delegate('click', 'h1', handler);
+    myView.undelegate('click', 'h1', handler);
+    myView.$('h1').trigger('click');
+    myView.$el.trigger('click');
+  });
+
+  QUnit.test('tagName can be provided as a string', function(assert) {
+    assert.expect(1);
+    var View = Backbone.View.extend({
+      tagName: 'span'
+    });
+
+    assert.equal(new View().el.tagName, 'SPAN');
+  });
+
+  QUnit.test('tagName can be provided as a function', function(assert) {
+    assert.expect(1);
+    var View = Backbone.View.extend({
+      tagName: function() {
+        return 'p';
+      }
+    });
+
+    assert.ok(new View().$el.is('p'));
+  });
+
+  QUnit.test('_ensureElement with DOM node el', function(assert) {
+    assert.expect(1);
+    var View = Backbone.View.extend({
+      el: document.body
+    });
+
+    assert.equal(new View().el, document.body);
+  });
+
+  QUnit.test('_ensureElement with string el', function(assert) {
+    assert.expect(3);
+    var View = Backbone.View.extend({
+      el: 'body'
+    });
+    assert.strictEqual(new View().el, document.body);
+
+    View = Backbone.View.extend({
+      el: '#testElement > h1'
+    });
+    assert.strictEqual(new View().el, $('#testElement > h1').get(0));
+
+    View = Backbone.View.extend({
+      el: '#nonexistent'
+    });
+    assert.ok(!new View().el);
+  });
+
+  QUnit.test('with className and id functions', function(assert) {
+    assert.expect(2);
+    var View = Backbone.View.extend({
+      className: function() {
+        return 'className';
+      },
+      id: function() {
+        return 'id';
+      }
+    });
+
+    assert.strictEqual(new View().el.className, 'className');
+    assert.strictEqual(new View().el.id, 'id');
+  });
+
+  QUnit.test('with attributes', function(assert) {
+    assert.expect(2);
+    var View = Backbone.View.extend({
+      attributes: {
+        'id': 'id',
+        'class': 'class'
+      }
+    });
+
+    assert.strictEqual(new View().el.className, 'class');
+    assert.strictEqual(new View().el.id, 'id');
+  });
+
+  QUnit.test('with attributes as a function', function(assert) {
+    assert.expect(1);
+    var View = Backbone.View.extend({
+      attributes: function() {
+        return {'class': 'dynamic'};
+      }
+    });
+
+    assert.strictEqual(new View().el.className, 'dynamic');
+  });
+
+  QUnit.test('should default to className/id properties', function(assert) {
+    assert.expect(4);
+    var View = Backbone.View.extend({
+      className: 'backboneClass',
+      id: 'backboneId',
+      attributes: {
+        'class': 'attributeClass',
+        'id': 'attributeId'
+      }
+    });
+
+    var myView = new View;
+    assert.strictEqual(myView.el.className, 'backboneClass');
+    assert.strictEqual(myView.el.id, 'backboneId');
+    assert.strictEqual(myView.$el.attr('class'), 'backboneClass');
+    assert.strictEqual(myView.$el.attr('id'), 'backboneId');
+  });
+
+  QUnit.test('multiple views per element', function(assert) {
+    assert.expect(3);
+    var count = 0;
+    var $el = $('<p></p>');
+
+    var View = Backbone.View.extend({
+      el: $el,
+      events: {
+        click: function() {
+          count++;
+        }
+      }
+    });
+
+    var view1 = new View;
+    $el.trigger('click');
+    assert.equal(1, count);
+
+    var view2 = new View;
+    $el.trigger('click');
+    assert.equal(3, count);
+
+    view1.delegateEvents();
+    $el.trigger('click');
+    assert.equal(5, count);
+  });
+
+  QUnit.test('custom events', function(assert) {
+    assert.expect(2);
+    var View = Backbone.View.extend({
+      el: $('body'),
+      events: {
+        fake$event: function() { assert.ok(true); }
+      }
+    });
+
+    var myView = new View;
+    $('body').trigger('fake$event').trigger('fake$event');
+
+    $('body').off('fake$event');
+    $('body').trigger('fake$event');
+  });
+
+  QUnit.test('#1048 - setElement uses provided object.', function(assert) {
+    assert.expect(2);
+    var $el = $('body');
+
+    var myView = new Backbone.View({el: $el});
+    assert.ok(myView.$el === $el);
+
+    myView.setElement($el = $($el));
+    assert.ok(myView.$el === $el);
+  });
+
+  QUnit.test('#986 - Undelegate before changing element.', function(assert) {
+    assert.expect(1);
+    var button1 = $('<button></button>');
+    var button2 = $('<button></button>');
+
+    var View = Backbone.View.extend({
+      events: {
+        click: function(e) {
+          assert.ok(myView.el === e.target);
+        }
+      }
+    });
+
+    var myView = new View({el: button1});
+    myView.setElement(button2);
+
+    button1.trigger('click');
+    button2.trigger('click');
+  });
+
+  QUnit.test('#1172 - Clone attributes object', function(assert) {
+    assert.expect(2);
+    var View = Backbone.View.extend({
+      attributes: {foo: 'bar'}
+    });
+
+    var view1 = new View({id: 'foo'});
+    assert.strictEqual(view1.el.id, 'foo');
+
+    var view2 = new View();
+    assert.ok(!view2.el.id);
+  });
+
+  QUnit.test('views stopListening', function(assert) {
+    assert.expect(0);
+    var View = Backbone.View.extend({
+      initialize: function() {
+        this.listenTo(this.model, 'all x', function(){ assert.ok(false); });
+        this.listenTo(this.collection, 'all x', function(){ assert.ok(false); });
+      }
+    });
+
+    var myView = new View({
+      model: new Backbone.Model,
+      collection: new Backbone.Collection
+    });
+
+    myView.stopListening();
+    myView.model.trigger('x');
+    myView.collection.trigger('x');
+  });
+
+  QUnit.test('Provide function for el.', function(assert) {
+    assert.expect(2);
+    var View = Backbone.View.extend({
+      el: function() {
+        return '<p><a></a></p>';
+      }
+    });
+
+    var myView = new View;
+    assert.ok(myView.$el.is('p'));
+    assert.ok(myView.$el.has('a'));
+  });
+
+  QUnit.test('events passed in options', function(assert) {
+    assert.expect(1);
+    var counter = 0;
+
+    var View = Backbone.View.extend({
+      el: '#testElement',
+      increment: function() {
+        counter++;
+      }
+    });
+
+    var myView = new View({
+      events: {
+        'click h1': 'increment'
+      }
+    });
+
+    myView.$('h1').trigger('click').trigger('click');
+    assert.equal(counter, 2);
+  });
+
+  QUnit.test('remove', function(assert) {
+    assert.expect(2);
+    var myView = new Backbone.View;
+    document.body.appendChild(view.el);
+
+    myView.delegate('click', function() { assert.ok(false); });
+    myView.listenTo(myView, 'all x', function() { assert.ok(false); });
+
+    assert.equal(myView.remove(), myView, '#remove returns the view instance');
+    myView.$el.trigger('click');
+    myView.trigger('x');
+
+    // In IE8 and below, parentNode still exists but is not document.body.
+    assert.notEqual(myView.el.parentNode, document.body);
+  });
+
+  QUnit.test('setElement', function(assert) {
+    assert.expect(3);
+    var myView = new Backbone.View({
+      events: {
+        click: function() { assert.ok(false); }
+      }
+    });
+    myView.events = {
+      click: function() { assert.ok(true); }
+    };
+    var oldEl = myView.el;
+    var $oldEl = myView.$el;
+
+    myView.setElement(document.createElement('div'));
+
+    $oldEl.click();
+    myView.$el.click();
+
+    assert.notEqual(oldEl, myView.el);
+    assert.notEqual($oldEl, myView.$el);
+  });
+
+})();
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/license.txt b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/license.txt
new file mode 100644
index 0000000..ba43b75
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/license.txt
@@ -0,0 +1,30 @@
+Software License Agreement (BSD License)
+
+Copyright (c) 2007, Parakey Inc.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of Parakey Inc. nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of Parakey Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/blank.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/blank.gif
new file mode 100644
index 0000000..6865c96
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/blank.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/buttonBg.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/buttonBg.png
new file mode 100644
index 0000000..f367b42
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/buttonBg.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.png
new file mode 100644
index 0000000..cd37a0d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/buttonBgHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/debugger.css b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/debugger.css
new file mode 100644
index 0000000..ba55c7e
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/debugger.css
@@ -0,0 +1,331 @@
+/* See license.txt for terms of usage */
+
+.panelNode-script {
+    overflow: hidden;
+    font-family: monospace;
+}
+
+/************************************************************************************************/
+
+.scriptTooltip {
+    position: fixed;
+    z-index: 2147483647;
+    padding: 2px 3px;
+    border: 1px solid #CBE087;
+    background: LightYellow;
+    font-family: monospace;
+    color: #000000;
+}
+
+/************************************************************************************************/
+
+.sourceBox {
+    /* TODO: xxxpedro problem with sourceBox and scrolling elements */
+    /*overflow: scroll; /* see issue 1479 */
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+}
+
+.sourceRow {
+    white-space: nowrap;
+    -moz-user-select: text;
+}
+
+.sourceRow.hovered {
+    background-color: #EEEEEE;
+}
+
+/************************************************************************************************/
+
+.sourceLine {
+    -moz-user-select: none;
+    margin-right: 10px;
+    border-right: 1px solid #CCCCCC;
+    padding: 0px 4px 0 20px;
+    background: #EEEEEE no-repeat 2px 0px;
+    color: #888888;
+    white-space: pre;
+    font-family: monospace; /* see issue 2953 */
+}
+
+.noteInToolTip { /* below sourceLine, so it overrides it */
+    background-color: #FFD472;
+}
+
+.useA11y .sourceBox .sourceViewport:focus .sourceLine {
+    background-color: #FFFFC0;
+    color: navy;
+    border-right: 1px solid black;
+}
+
+.useA11y .sourceBox .sourceViewport:focus {
+    outline: none;
+}
+
+.a11y1emSize {
+    width: 1em;
+    height: 1em;
+    position: absolute;
+}
+
+.useA11y .panelStatusLabel:focus {
+    outline-offset: -2px !important;
+ }
+
+.sourceBox > .sourceRow > .sourceLine {
+    cursor: pointer;
+}
+
+.sourceLine:hover {
+    text-decoration: none;
+}
+
+.sourceRowText {
+    white-space: pre;
+}
+
+.sourceRow[exe_line="true"] {
+    outline: 1px solid #D9D9B6;
+    margin-right: 1px;
+    background-color: lightgoldenrodyellow;
+}
+
+.sourceRow[executable="true"] > .sourceLine {
+    content: "-";
+    color: #4AA02C;  /* Spring Green */
+    font-weight: bold;
+}
+
+.sourceRow[exe_line="true"] > .sourceLine {
+    background-image: url(chrome://firebug/skin/exe.png);
+    color: #000000;
+}
+
+.sourceRow[breakpoint="true"] > .sourceLine {
+    background-image: url(chrome://firebug/skin/breakpoint.png);
+}
+
+.sourceRow[breakpoint="true"][condition="true"] > .sourceLine {
+    background-image: url(chrome://firebug/skin/breakpointCondition.png);
+}
+
+.sourceRow[breakpoint="true"][disabledBreakpoint="true"] > .sourceLine {
+    background-image: url(chrome://firebug/skin/breakpointDisabled.png);
+}
+
+.sourceRow[breakpoint="true"][exe_line="true"] > .sourceLine {
+    background-image: url(chrome://firebug/skin/breakpointExe.png);
+}
+
+.sourceRow[breakpoint="true"][exe_line="true"][disabledBreakpoint="true"] > .sourceLine {
+    background-image: url(chrome://firebug/skin/breakpointDisabledExe.png);
+}
+
+.sourceLine.editing {
+    background-image: url(chrome://firebug/skin/breakpoint.png);
+}
+
+/************************************************************************************************/
+
+.conditionEditor {
+    z-index: 2147483647;
+    position: absolute;
+    margin-top: 0;
+    left: 2px;
+    width: 90%;
+}
+
+.conditionEditorInner {
+    position: relative;
+    top: -26px;
+    height: 0;
+}
+
+.conditionCaption {
+    margin-bottom: 2px;
+    font-family: Lucida Grande, sans-serif;
+    font-weight: bold;
+    font-size: 11px;
+    color: #226679;
+}
+
+.conditionInput {
+    width: 100%;
+    border: 1px solid #0096C0;
+    font-family: monospace;
+    font-size: inherit;
+}
+
+.conditionEditorInner1 {
+    padding-left: 37px;
+    background: url(condBorders.png) repeat-y;
+}
+
+.conditionEditorInner2 {
+    padding-right: 25px;
+    background: url(condBorders.png) repeat-y 100% 0;
+}
+
+.conditionEditorTop1 {
+    background: url(condCorners.png) no-repeat 100% 0;
+    margin-left: 37px;
+    height: 35px;
+}
+
+.conditionEditorTop2 {
+    position: relative;
+    left: -37px;
+    width: 37px;
+    height: 35px;
+    background: url(condCorners.png) no-repeat;
+}
+
+.conditionEditorBottom1 {
+    background: url(condCorners.png) no-repeat 100% 100%;
+    margin-left: 37px;
+    height: 33px;
+}
+
+.conditionEditorBottom2 {
+    position: relative;    left: -37px;
+    width: 37px;
+    height: 33px;
+    background: url(condCorners.png) no-repeat 0 100%;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.upsideDown {
+    margin-top: 2px;
+}
+
+.upsideDown .conditionEditorInner {
+    top: -8px;
+}
+
+.upsideDown .conditionEditorInner1 {
+    padding-left: 33px;
+    background: url(condBordersUps.png) repeat-y;
+}
+
+.upsideDown .conditionEditorInner2 {
+    padding-right: 25px;
+    background: url(condBordersUps.png) repeat-y 100% 0;
+}
+
+.upsideDown .conditionEditorTop1 {
+    background: url(condCornersUps.png) no-repeat 100% 0;
+    margin-left: 33px;
+    height: 25px;
+}
+
+.upsideDown .conditionEditorTop2 {
+    position: relative;
+    left: -33px;
+    width: 33px;
+    height: 25px;
+    background: url(condCornersUps.png) no-repeat;
+}
+
+.upsideDown .conditionEditorBottom1 {
+    background: url(condCornersUps.png) no-repeat 100% 100%;
+    margin-left: 33px;
+    height: 43px;
+}
+
+.upsideDown .conditionEditorBottom2 {
+    position: relative;
+    left: -33px;
+    width: 33px;
+    height: 43px;
+    background: url(condCornersUps.png) no-repeat 0 100%;
+}
+
+/************************************************************************************************/
+
+.breakpointsGroupListBox {
+  overflow: hidden;
+}
+
+.breakpointBlockHead {
+    position: relative;
+    padding-top: 4px;
+}
+
+.breakpointBlockHead > .checkbox {
+    margin-right: 4px;
+}
+
+.breakpointBlockHead > .objectLink-sourceLink {
+    top: 4px;
+    right: 20px;
+    background-color: #FFFFFF; /* issue 3308 */
+}
+
+.breakpointBlockHead > .closeButton {
+    position: absolute;
+    top: 2px;
+    right: 2px;
+}
+
+.breakpointCheckbox {
+    margin-top: 0;
+    vertical-align: top;
+}
+
+.breakpointName {
+    margin-left: 4px;
+    font-weight: bold;
+}
+
+.breakpointRow[aria-checked="false"] > .breakpointBlockHead > *,
+.breakpointRow[aria-checked="false"] > .breakpointCode {
+    opacity: 0.5;
+}
+
+.breakpointRow[aria-checked="false"] .breakpointCheckbox,
+.breakpointRow[aria-checked="false"] .objectLink-sourceLink,
+.breakpointRow[aria-checked="false"] .closeButton,
+.breakpointRow[aria-checked="false"] .breakpointMutationType {
+    opacity: 1.0 !important;
+}
+
+.breakpointCode {
+    overflow: hidden;
+    white-space: nowrap;
+    padding-left: 24px;
+    padding-bottom: 2px;
+    border-bottom: 1px solid #D7D7D7;
+    font-family: monospace;
+    color: DarkGreen;
+}
+
+.breakpointCondition {
+    white-space: nowrap;
+    padding-left: 24px;
+    padding-bottom: 2px;
+    border-bottom: 1px solid #D7D7D7;
+    font-family: monospace;
+    color: Gray;
+}
+
+.breakpointBlock-breakpoints > .groupHeader {
+    display: none;
+}
+
+.breakpointBlock-monitors > .breakpointCode {
+    padding: 0;
+}
+
+.breakpointBlock-errorBreakpoints .breakpointCheckbox,
+.breakpointBlock-monitors .breakpointCheckbox {
+    display: none;
+}
+
+.breakpointHeader {
+    margin: 0 !important;
+    border-top: none !important;
+}
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/detach.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/detach.png
new file mode 100644
index 0000000..0ddb9a1
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/detach.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/detachHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/detachHover.png
new file mode 100644
index 0000000..e419272
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/detachHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disable.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disable.gif
new file mode 100644
index 0000000..dd9eb0e
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disable.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disable.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disable.png
new file mode 100644
index 0000000..c28bcdf
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disable.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disableHover.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disableHover.gif
new file mode 100644
index 0000000..70565a8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disableHover.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disableHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disableHover.png
new file mode 100644
index 0000000..26fe375
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/disableHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/down.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/down.png
new file mode 100644
index 0000000..acbbd30
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/down.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/downActive.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/downActive.png
new file mode 100644
index 0000000..f4312b2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/downActive.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/downHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/downHover.png
new file mode 100644
index 0000000..8144e63
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/downHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.png
new file mode 100644
index 0000000..0c377e3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon-sm.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon.gif
new file mode 100644
index 0000000..8ee8116
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon.png
new file mode 100644
index 0000000..2d75261
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/errorIcon.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css
new file mode 100644
index 0000000..42f9faf
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug-1.3a2.css
@@ -0,0 +1,817 @@
+.fbBtnPressed {
+    background: #ECEBE3;
+    padding: 3px 6px 2px 7px !important;
+    margin: 1px 0 0 1px;
+    _margin: 1px -1px 0 1px;
+    border: 1px solid #ACA899 !important;
+    border-color: #ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;
+}
+
+.fbToolbarButtons {
+    display: none;
+}
+
+#fbStatusBarBox {
+    display: none;
+}
+
+/************************************************************************************************
+ Error Popup
+*************************************************************************************************/
+#fbErrorPopup {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    height: 19px;
+    width: 75px;
+    background: url(sprite.png) #f1f2ee 0 0;
+    z-index: 999;
+}
+
+#fbErrorPopupContent {
+    position: absolute;
+    right: 0;
+    top: 1px;
+    height: 18px;
+    width: 75px;
+    _width: 74px;
+    border-left: 1px solid #aca899;
+}
+
+#fbErrorIndicator {
+    position: absolute;
+    top: 2px;
+    right: 5px;
+}
+
+
+
+
+
+
+
+
+
+
+.fbBtnInspectActive {
+    background: #aaa;
+    color: #fff !important;
+}
+
+/************************************************************************************************
+ General
+*************************************************************************************************/
+html, body {
+    margin: 0;
+    padding: 0;
+    overflow: hidden;
+}
+
+body {
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-size: 11px;
+    background: #fff;    
+}
+
+.clear {
+    clear: both;
+}
+
+/************************************************************************************************
+ Mini Chrome
+*************************************************************************************************/
+#fbMiniChrome {
+    display: none;
+    right: 0;
+    height: 27px;
+    background: url(sprite.png) #f1f2ee 0 0;
+    margin-left: 1px;
+}
+
+#fbMiniContent {
+    display: block;
+    position: relative;
+    left: -1px;
+    right: 0;
+    top: 1px;
+    height: 25px;
+    border-left: 1px solid #aca899;
+}
+
+#fbToolbarSearch {
+    float: right;
+    border: 1px solid #ccc;
+    margin: 0 5px 0 0;
+    background: #fff url(search.png) no-repeat 4px 2px;
+    padding-left: 20px;    
+    font-size: 11px;
+}
+
+#fbToolbarErrors {
+    float: right;
+    margin: 1px 4px 0 0;
+    font-size: 11px;
+}
+
+#fbLeftToolbarErrors {
+    float: left;
+    margin: 7px 0px 0 5px;
+    font-size: 11px;
+}
+
+.fbErrors {
+    padding-left: 20px;
+    height: 14px;
+    background: url(errorIcon.png) no-repeat;
+    color: #f00;
+    font-weight: bold;    
+}
+
+#fbMiniErrors {
+    display: inline;
+    display: none;
+    float: right;
+    margin: 5px 2px 0 5px;
+}
+
+#fbMiniIcon {
+    float: right;
+    margin: 3px 4px 0;
+    height: 20px;
+    width: 20px;
+    float: right;    
+    background: url(sprite.png) 0 -135px;
+    cursor: pointer;
+}
+
+
+/************************************************************************************************
+ Master Layout
+*************************************************************************************************/
+#fbChrome {
+    position: fixed;
+    overflow: hidden;
+    height: 100%;
+    width: 100%;
+    border-collapse: collapse;
+    background: #fff;
+}
+
+#fbTop {
+    height: 49px;
+}
+
+#fbToolbar {
+    position: absolute;
+    z-index: 5;
+    width: 100%;
+    top: 0;
+    background: url(sprite.png) #f1f2ee 0 0;
+    height: 27px;
+    font-size: 11px;
+    overflow: hidden;
+}
+
+#fbPanelBarBox {
+    top: 27px;
+    position: absolute;
+    z-index: 8;
+    width: 100%;
+    background: url(sprite.png) #dbd9c9 0 -27px;
+    height: 22px;
+}
+
+#fbContent {
+    height: 100%;
+    vertical-align: top;
+}
+
+#fbBottom {
+    height: 18px;
+    background: #fff;
+}
+
+/************************************************************************************************
+ Sub-Layout 
+*************************************************************************************************/
+
+/* fbToolbar 
+*************************************************************************************************/
+#fbToolbarIcon {
+    float: left;
+    padding: 4px 5px 0;
+}
+
+#fbToolbarIcon a {
+    display: block;
+    height: 20px;
+    width: 20px;
+    background: url(sprite.png) 0 -135px;
+    text-decoration: none;
+    cursor: default;
+}
+
+#fbToolbarButtons {
+    float: left;
+    padding: 4px 2px 0 5px;
+}
+
+#fbToolbarButtons a {
+    text-decoration: none;
+    display: block;
+    float: left;
+    color: #000;
+    padding: 4px 8px 4px;
+    cursor: default;
+}
+
+#fbToolbarButtons a:hover {
+    color: #333;
+    padding: 3px 7px 3px;
+    border: 1px solid #fff;
+    border-bottom: 1px solid #bbb;
+    border-right: 1px solid #bbb;
+}
+
+#fbStatusBarBox {
+    position: relative;
+    top: 5px;
+    line-height: 19px;
+    cursor: default;    
+}
+
+.fbToolbarSeparator{
+    overflow: hidden;
+    border: 1px solid;
+    border-color: transparent #fff transparent #777;
+    _border-color: #eee #fff #eee #777;
+    height: 7px;
+    margin: 10px 6px 0 0;
+    float: left;
+}
+
+.fbStatusBar span {
+    color: #808080;
+    padding: 0 4px 0 0;
+}
+
+.fbStatusBar span a {
+    text-decoration: none;
+    color: black;
+}
+
+.fbStatusBar span a:hover {
+    color: blue;
+    cursor: pointer;    
+}
+
+
+#fbWindowButtons {
+    position: absolute;
+    white-space: nowrap;
+    right: 0;
+    top: 0;
+    height: 17px;
+    _width: 50px;
+    padding: 5px 0 5px 5px;
+    z-index: 6;
+    background: url(sprite.png) #f1f2ee 0 0;
+}
+
+/* fbPanelBarBox
+*************************************************************************************************/
+
+#fbPanelBar1 {
+    width: 255px; /* fixed width to avoid tabs breaking line */
+    z-index: 8;
+    left: 0;
+    white-space: nowrap;
+    background: url(sprite.png) #dbd9c9 0 -27px;
+    position: absolute;
+    left: 4px;
+}
+
+#fbPanelBar2Box {
+    background: url(sprite.png) #dbd9c9 0 -27px;
+    position: absolute;
+    height: 22px;
+    width: 300px; /* fixed width to avoid tabs breaking line */
+    z-index: 9;
+    right: 0;
+}
+
+#fbPanelBar2 {
+    position: absolute;
+    width: 290px; /* fixed width to avoid tabs breaking line */
+    height: 22px;
+    padding-left: 10px;
+}
+
+/* body 
+*************************************************************************************************/
+.fbPanel {
+    display: none;
+}
+
+#fbPanelBox1, #fbPanelBox2 {
+    max-height: inherit;
+    height: 100%;
+    font-size: 11px;
+}
+
+#fbPanelBox2 {
+    background: #fff;
+}
+
+#fbPanelBox2 {
+    width: 300px;
+    background: #fff;
+}
+
+#fbPanel2 {
+    padding-left: 6px;
+    background: #fff;
+}
+
+.hide {
+    overflow: hidden !important;
+    position: fixed !important;
+    display: none !important;
+    visibility: hidden !important;
+}
+
+/* fbBottom 
+*************************************************************************************************/
+
+#fbCommand {
+    height: 18px;
+}
+
+#fbCommandBox {
+    position: absolute;
+    width: 100%;
+    height: 18px;
+    bottom: 0;
+    overflow: hidden;
+    z-index: 9;
+    background: #fff;
+    border: 0;
+    border-top: 1px solid #ccc;
+}
+
+#fbCommandIcon {
+    position: absolute;
+    color: #00f;
+    top: 2px;
+    left: 7px;
+    display: inline;
+    font: 11px Monaco, monospace;
+    z-index: 10;
+}
+
+#fbCommandLine {
+    position: absolute;
+    width: 100%;
+    top: 0;
+    left: 0;
+    border: 0;
+    margin: 0;
+    padding: 2px 0 2px 32px;
+    font: 11px Monaco, monospace;
+    z-index: 9;
+}
+
+div.fbFitHeight {
+    overflow: auto;
+    _position: absolute;
+}
+
+
+/************************************************************************************************
+ Layout Controls
+*************************************************************************************************/
+
+/* fbToolbar buttons 
+*************************************************************************************************/
+#fbWindowButtons a {
+    font-size: 1px;
+    width: 16px;
+    height: 16px;
+    display: block;
+    float: right;
+    margin-right: 4px;
+    text-decoration: none;
+    cursor: default;
+}
+
+#fbWindow_btClose {
+    background: url(sprite.png) 0 -119px;
+}
+
+#fbWindow_btClose:hover {
+    background: url(sprite.png) -16px -119px;
+}
+
+#fbWindow_btDetach {
+    background: url(sprite.png) -32px -119px;
+}
+
+#fbWindow_btDetach:hover {
+    background: url(sprite.png) -48px -119px;
+}
+
+/* fbPanelBarBox tabs 
+*************************************************************************************************/
+.fbTab {
+    text-decoration: none;
+    display: none;
+    float: left;
+    width: auto;
+    float: left;
+    cursor: default;
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-size: 11px;
+    font-weight: bold;
+    height: 22px;
+    color: #565656;
+}
+
+.fbPanelBar span {
+    display: block;
+    float: left;
+}
+
+.fbPanelBar .fbTabL,.fbPanelBar .fbTabR {
+    height: 22px;
+    width: 8px;
+}
+
+.fbPanelBar .fbTabText {
+    padding: 4px 1px 0;
+}
+
+a.fbTab:hover {
+    background: url(sprite.png) 0 -73px;
+}
+
+a.fbTab:hover .fbTabL {
+    background: url(sprite.png) -16px -96px;
+}
+
+a.fbTab:hover .fbTabR {
+    background: url(sprite.png) -24px -96px;
+}
+
+.fbSelectedTab {
+    background: url(sprite.png) #f1f2ee 0 -50px !important;
+    color: #000;
+}
+
+.fbSelectedTab .fbTabL {
+    background: url(sprite.png) 0 -96px !important;
+}
+
+.fbSelectedTab .fbTabR {
+    background: url(sprite.png) -8px -96px !important;
+}
+
+/* splitters 
+*************************************************************************************************/
+#fbHSplitter {
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 5px;
+    overflow: hidden;
+    cursor: n-resize !important;
+    background: url(pixel_transparent.gif);
+    z-index: 9;
+}
+
+#fbHSplitter.fbOnMovingHSplitter {
+    height: 100%;
+    z-index: 100;
+}
+
+.fbVSplitter {
+    background: #ece9d8;
+    color: #000;
+    border: 1px solid #716f64;
+    border-width: 0 1px;
+    border-left-color: #aca899;
+    width: 4px;
+    cursor: e-resize;
+    overflow: hidden;
+    right: 294px;
+    text-decoration: none;
+    z-index: 9;
+    position: absolute;
+    height: 100%;
+    top: 27px;
+    _width: 6px;
+}
+
+/************************************************************************************************/
+div.lineNo {
+    font: 11px Monaco, monospace;
+    float: left;
+    display: inline;
+    position: relative;
+    margin: 0;
+    padding: 0 5px 0 20px;
+    background: #eee;
+    color: #888;
+    border-right: 1px solid #ccc;
+    text-align: right;
+}
+
+pre.nodeCode {
+    font: 11px Monaco, monospace;
+    margin: 0;
+    padding-left: 10px;
+    overflow: hidden;
+    /*
+    _width: 100%;
+    /**/
+}
+
+/************************************************************************************************/
+.nodeControl {
+    margin-top: 3px;
+    margin-left: -14px;
+    float: left;
+    width: 9px;
+    height: 9px;
+    overflow: hidden;
+    cursor: default;
+    background: url(tree_open.gif);
+    _float: none;
+    _display: inline;
+    _position: absolute;
+}
+
+div.nodeMaximized {
+    background: url(tree_close.gif);
+}
+
+div.objectBox-element {
+    padding: 1px 3px;
+}
+.objectBox-selector{
+    cursor: default;
+}
+
+.selectedElement{
+    background: highlight;
+    /* background: url(roundCorner.svg); Opera */
+    color: #fff !important;
+}
+.selectedElement span{
+    color: #fff !important;
+}
+
+/* Webkit CSS Hack - bug in "highlight" named color */ 
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+    .selectedElement{
+      background: #316AC5;
+      color: #fff !important;
+    }
+}
+
+/************************************************************************************************/
+/************************************************************************************************/
+.logRow * {
+    font-size: 11px;
+}
+
+.logRow {
+    position: relative;
+    border-bottom: 1px solid #D7D7D7;
+    padding: 2px 4px 1px 6px;
+    background-color: #FFFFFF;
+}
+
+.logRow-command {
+    font-family: Monaco, monospace;
+    color: blue;
+}
+
+.objectBox-string,
+.objectBox-text,
+.objectBox-number,
+.objectBox-function,
+.objectLink-element,
+.objectLink-textNode,
+.objectLink-function,
+.objectBox-stackTrace,
+.objectLink-profile {
+    font-family: Monaco, monospace;
+}
+
+.objectBox-null {
+    padding: 0 2px;
+    border: 1px solid #666666;
+    background-color: #888888;
+    color: #FFFFFF;
+}
+
+.objectBox-string {
+    color: red;
+    white-space: pre;
+}
+
+.objectBox-number {
+    color: #000088;
+}
+
+.objectBox-function {
+    color: DarkGreen;
+}
+
+.objectBox-object {
+    color: DarkGreen;
+    font-weight: bold;
+    font-family: Lucida Grande, sans-serif;
+}
+
+.objectBox-array {
+    color: #000;
+}
+
+/************************************************************************************************/
+.logRow-info,.logRow-error,.logRow-warning {
+    background: #fff no-repeat 2px 2px;
+    padding-left: 20px;
+    padding-bottom: 3px;
+}
+
+.logRow-info {
+    background-image: url(infoIcon.png);
+}
+
+.logRow-warning {
+    background-color: cyan;
+    background-image: url(warningIcon.png);
+}
+
+.logRow-error {
+    background-color: LightYellow;
+    background-image: url(errorIcon.png);
+    color: #f00;
+}
+
+.errorMessage {
+    vertical-align: top;
+    color: #f00;
+}
+
+.objectBox-sourceLink {
+    position: absolute;
+    right: 4px;
+    top: 2px;
+    padding-left: 8px;
+    font-family: Lucida Grande, sans-serif;
+    font-weight: bold;
+    color: #0000FF;
+}
+
+/************************************************************************************************/
+.logRow-group {
+    background: #EEEEEE;
+    border-bottom: none;
+}
+
+.logGroup {
+    background: #EEEEEE;
+}
+
+.logGroupBox {
+    margin-left: 24px;
+    border-top: 1px solid #D7D7D7;
+    border-left: 1px solid #D7D7D7;
+}
+
+/************************************************************************************************/
+.selectorTag,.selectorId,.selectorClass {
+    font-family: Monaco, monospace;
+    font-weight: normal;
+}
+
+.selectorTag {
+    color: #0000FF;
+}
+
+.selectorId {
+    color: DarkBlue;
+}
+
+.selectorClass {
+    color: red;
+}
+
+/************************************************************************************************/
+.objectBox-element {
+    font-family: Monaco, monospace;
+    color: #000088;
+}
+
+.nodeChildren {
+    padding-left: 26px;
+}
+
+.nodeTag {
+    color: blue;
+    cursor: pointer;
+}
+
+.nodeValue {
+    color: #FF0000;
+    font-weight: normal;
+}
+
+.nodeText,.nodeComment {
+    margin: 0 2px;
+    vertical-align: top;
+}
+
+.nodeText {
+    color: #333333;
+    font-family: Monaco, monospace;
+}
+
+.nodeComment {
+    color: DarkGreen;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeHidden, .nodeHidden * {
+    color: #888888;
+}
+
+.nodeHidden .nodeTag {
+    color: #5F82D9;
+}
+
+.nodeHidden .nodeValue {
+    color: #D86060;
+}
+
+.selectedElement .nodeHidden, .selectedElement .nodeHidden * {
+    color: SkyBlue !important;
+}
+
+
+/************************************************************************************************/
+.log-object {
+    /*
+    _position: relative;
+    _height: 100%;
+    /**/
+}
+
+.property {
+    position: relative;
+    clear: both;
+    height: 15px;
+}
+
+.propertyNameCell {
+    vertical-align: top;
+    float: left;
+    width: 28%;
+    position: absolute;
+    left: 0;
+    z-index: 0;
+}
+
+.propertyValueCell {
+    float: right;
+    width: 68%;
+    background: #fff;
+    position: absolute;
+    padding-left: 5px;
+    display: table-cell;
+    right: 0;
+    z-index: 1;
+    /*
+    _position: relative;
+    /**/
+}
+
+.propertyName {
+    font-weight: bold;
+}
+
+.FirebugPopup {
+    height: 100% !important;
+}
+
+.FirebugPopup #fbWindowButtons {
+    display: none !important;
+}
+
+.FirebugPopup #fbHSplitter {
+    display: none !important;
+}
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css
new file mode 100644
index 0000000..13a41d2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.IE6.css
@@ -0,0 +1,20 @@
+/************************************************************************************************/
+#fbToolbarSearch {
+    background-image: url(search.gif) !important;
+}
+/************************************************************************************************/
+.fbErrors {
+    background-image: url(errorIcon.gif) !important;
+}
+/************************************************************************************************/
+.logRow-info {
+    background-image: url(infoIcon.gif) !important;
+}
+
+.logRow-warning {
+    background-image: url(warningIcon.gif) !important;
+}
+
+.logRow-error {
+    background-image: url(errorIcon.gif) !important;
+}
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.css b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.css
new file mode 100644
index 0000000..a1465ec
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.css
@@ -0,0 +1,3147 @@
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* Loose */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*
+.netInfoResponseHeadersTitle, netInfoResponseHeadersBody {
+    display: none;
+}
+/**/
+
+.obscured {
+    left: -999999px !important;
+}
+
+/* IE6 need a separated rule, otherwise it will not recognize it */
+.collapsed {
+    display: none;
+}
+
+[collapsed="true"] {
+    display: none;
+}
+
+#fbCSS {
+    padding: 0 !important;
+}
+
+.cssPropDisable {
+    float: left;
+    display: block;
+    width: 2em;
+    cursor: default;
+}
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* panelBase */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+
+/************************************************************************************************/
+
+.infoTip {
+    z-index: 2147483647;
+    position: fixed;
+    padding: 2px 3px;
+    border: 1px solid #CBE087;
+    background: LightYellow;
+    font-family: Monaco, monospace;
+    color: #000000;
+    display: none;
+    white-space: nowrap;
+    pointer-events: none;
+}
+
+.infoTip[active="true"] {
+    display: block;
+}
+
+.infoTipLoading {
+    width: 16px;
+    height: 16px;
+    background: url(chrome://firebug/skin/loading_16.gif) no-repeat;
+}
+
+.infoTipImageBox {
+	font-size: 11px;
+    min-width: 100px;
+    text-align: center;
+}
+
+.infoTipCaption {
+	font-size: 11px;
+    font: Monaco, monospace;
+}
+
+.infoTipLoading > .infoTipImage,
+.infoTipLoading > .infoTipCaption {
+    display: none;
+}
+
+/************************************************************************************************/
+
+h1.groupHeader {
+    padding: 2px 4px;
+    margin: 0 0 4px 0;
+    border-top: 1px solid #CCCCCC;
+    border-bottom: 1px solid #CCCCCC;
+    background: #eee url(group.gif) repeat-x;
+    font-size: 11px;
+    font-weight: bold;
+    _position: relative;
+}
+
+/************************************************************************************************/
+
+.inlineEditor,
+.fixedWidthEditor {
+    z-index: 2147483647;
+    position: absolute;
+    display: none;
+}
+
+.inlineEditor {
+    margin-left: -6px;
+    margin-top: -3px;
+    /*
+    _margin-left: -7px;
+    _margin-top: -5px;
+    /**/
+}
+
+.textEditorInner,
+.fixedWidthEditor {
+    margin: 0 0 0 0 !important;
+    padding: 0;
+    border: none !important;
+    font: inherit;
+    text-decoration: inherit;
+    background-color: #FFFFFF;
+}
+
+.fixedWidthEditor {
+    border-top: 1px solid #888888 !important;
+    border-bottom: 1px solid #888888 !important;
+}
+
+.textEditorInner {
+    position: relative;
+    top: -7px;
+    left: -5px;
+    
+    outline: none;
+    resize: none;
+    
+    /*
+    _border: 1px solid #999 !important;
+    _padding: 1px !important;
+    _filter:progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color="#55404040");
+    /**/
+}
+
+.textEditorInner1 {
+    padding-left: 11px;
+    background: url(textEditorBorders.png) repeat-y;
+    _background: url(textEditorBorders.gif) repeat-y;
+    _overflow: hidden;
+}
+
+.textEditorInner2 {
+    position: relative;
+    padding-right: 2px;
+    background: url(textEditorBorders.png) repeat-y 100% 0;
+    _background: url(textEditorBorders.gif) repeat-y 100% 0;
+    _position: fixed;
+}
+
+.textEditorTop1 {
+    background: url(textEditorCorners.png) no-repeat 100% 0;
+    margin-left: 11px;
+    height: 10px;
+    _background: url(textEditorCorners.gif) no-repeat 100% 0;
+    _overflow: hidden;
+}
+
+.textEditorTop2 {
+    position: relative;
+    left: -11px;
+    width: 11px;
+    height: 10px;
+    background: url(textEditorCorners.png) no-repeat;
+    _background: url(textEditorCorners.gif) no-repeat;
+}
+
+.textEditorBottom1 {
+    position: relative;
+    background: url(textEditorCorners.png) no-repeat 100% 100%;
+    margin-left: 11px;
+    height: 12px;
+    _background: url(textEditorCorners.gif) no-repeat 100% 100%;
+}
+
+.textEditorBottom2 {
+    position: relative;
+    left: -11px;
+    width: 11px;
+    height: 12px;
+    background: url(textEditorCorners.png) no-repeat 0 100%;
+    _background: url(textEditorCorners.gif) no-repeat 0 100%;
+}
+
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* CSS */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+
+/* See license.txt for terms of usage */
+
+.panelNode-css {
+    overflow-x: hidden;
+}
+
+.cssSheet > .insertBefore {
+    height: 1.5em;
+}
+
+.cssRule {
+    position: relative;
+    margin: 0;
+    padding: 1em 0 0 6px;
+    font-family: Monaco, monospace;
+    color: #000000;
+}
+
+.cssRule:first-child {
+    padding-top: 6px;
+}
+
+.cssElementRuleContainer {
+    position: relative;
+}
+
+.cssHead {
+    padding-right: 150px;
+}
+
+.cssProp {
+    /*padding-left: 2em;*/
+}
+
+.cssPropName {
+    color: DarkGreen;
+}
+
+.cssPropValue {
+    margin-left: 8px;
+    color: DarkBlue;
+}
+
+.cssOverridden span {
+    text-decoration: line-through;
+}
+
+.cssInheritedRule {
+}
+
+.cssInheritLabel {
+    margin-right: 0.5em;
+    font-weight: bold;
+}
+
+.cssRule .objectLink-sourceLink {
+    top: 0;
+}
+
+.cssProp.editGroup:hover {
+    background: url(disable.png) no-repeat 2px 1px;
+    _background: url(disable.gif) no-repeat 2px 1px;
+}
+
+.cssProp.editGroup.editing {
+    background: none;
+}
+
+.cssProp.disabledStyle {
+    background: url(disableHover.png) no-repeat 2px 1px;
+    _background: url(disableHover.gif) no-repeat 2px 1px;
+    opacity: 1;
+    color: #CCCCCC;
+}
+
+.disabledStyle .cssPropName,
+.disabledStyle .cssPropValue {
+    color: #CCCCCC;
+}
+
+.cssPropValue.editing + .cssSemi,
+.inlineExpander + .cssSemi {
+    display: none;
+}
+
+.cssPropValue.editing {
+    white-space: nowrap;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.stylePropName {
+    font-weight: bold;
+    padding: 0 4px 4px 4px;
+    width: 50%;
+}
+
+.stylePropValue {
+    width: 50%;
+}
+/*
+.useA11y .a11yCSSView .focusRow:focus {
+    outline: none;
+    background-color: transparent
+ }
+ 
+ .useA11y .a11yCSSView .focusRow:focus .cssSelector, 
+ .useA11y .a11yCSSView .focusRow:focus .cssPropName, 
+ .useA11y .a11yCSSView .focusRow:focus .cssPropValue,
+ .useA11y .a11yCSSView .computedStyleRow:focus, 
+ .useA11y .a11yCSSView .groupHeader:focus {
+    outline: 2px solid #FF9933;
+    outline-offset: -2px;
+    background-color: #FFFFD6;
+ }
+ 
+ .useA11y .a11yCSSView .groupHeader:focus {
+    outline-offset: -2px;
+ }
+/**/
+
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* Net */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+
+/* See license.txt for terms of usage */
+
+.panelNode-net {
+    overflow-x: hidden;
+}
+
+.netTable {
+    width: 100%;
+}
+
+/************************************************************************************************/
+
+.hideCategory-undefined .category-undefined,
+.hideCategory-html .category-html,
+.hideCategory-css .category-css,
+.hideCategory-js .category-js,
+.hideCategory-image .category-image,
+.hideCategory-xhr .category-xhr,
+.hideCategory-flash .category-flash,
+.hideCategory-txt .category-txt,
+.hideCategory-bin .category-bin {
+    display: none;
+}
+
+/************************************************************************************************/
+
+.netHeadRow {
+    background: url(chrome://firebug/skin/group.gif) repeat-x #FFFFFF;
+}
+
+.netHeadCol {
+    border-bottom: 1px solid #CCCCCC;
+    padding: 2px 4px 2px 18px;
+    font-weight: bold;
+}
+
+.netHeadLabel {
+    white-space: nowrap;
+    overflow: hidden;
+}
+
+/************************************************************************************************/
+/* Header for Net panel table */
+
+.netHeaderRow {
+    height: 16px;
+}
+
+.netHeaderCell {
+    cursor: pointer;
+    -moz-user-select: none;
+    border-bottom: 1px solid #9C9C9C;
+    padding: 0 !important;
+    font-weight: bold;
+    background: #BBBBBB url(chrome://firebug/skin/tableHeader.gif) repeat-x;
+    white-space: nowrap;
+}
+
+.netHeaderRow > .netHeaderCell:first-child > .netHeaderCellBox {
+    padding: 2px 14px 2px 18px;
+}
+
+.netHeaderCellBox {
+    padding: 2px 14px 2px 10px;
+    border-left: 1px solid #D9D9D9;
+    border-right: 1px solid #9C9C9C;
+}
+
+.netHeaderCell:hover:active {
+    background: #959595 url(chrome://firebug/skin/tableHeaderActive.gif) repeat-x;
+}
+
+.netHeaderSorted {
+    background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;
+}
+
+.netHeaderSorted > .netHeaderCellBox {
+    border-right-color: #6B7C93;
+    background: url(chrome://firebug/skin/arrowDown.png) no-repeat right;
+}
+
+.netHeaderSorted.sortedAscending > .netHeaderCellBox {
+    background-image: url(chrome://firebug/skin/arrowUp.png);
+}
+
+.netHeaderSorted:hover:active {
+    background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;
+}
+
+/************************************************************************************************/
+/* Breakpoints */
+
+.panelNode-net .netRowHeader {
+    display: block;
+}
+
+.netRowHeader {
+    cursor: pointer;
+    display: none;
+    height: 15px;
+    margin-right: 0 !important;
+}
+
+/* Display brekpoint disc */
+.netRow .netRowHeader {
+    background-position: 5px 1px;
+}
+
+.netRow[breakpoint="true"] .netRowHeader {
+    background-image: url(chrome://firebug/skin/breakpoint.png);
+}
+
+.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader {
+    background-image: url(chrome://firebug/skin/breakpointDisabled.png);
+}
+
+.netRow.category-xhr:hover .netRowHeader {
+    background-color: #F6F6F6;
+}
+
+#netBreakpointBar {
+    max-width: 38px;
+}
+
+#netHrefCol > .netHeaderCellBox {
+    border-left: 0px;
+}
+
+.netRow .netRowHeader {
+    width: 3px;
+}
+
+.netInfoRow .netRowHeader {
+    display: table-cell;
+}
+
+/************************************************************************************************/
+/* Column visibility */
+
+.netTable[hiddenCols~=netHrefCol] TD[id="netHrefCol"],
+.netTable[hiddenCols~=netHrefCol] TD.netHrefCol,
+.netTable[hiddenCols~=netStatusCol] TD[id="netStatusCol"],
+.netTable[hiddenCols~=netStatusCol] TD.netStatusCol,
+.netTable[hiddenCols~=netDomainCol] TD[id="netDomainCol"],
+.netTable[hiddenCols~=netDomainCol] TD.netDomainCol,
+.netTable[hiddenCols~=netSizeCol] TD[id="netSizeCol"],
+.netTable[hiddenCols~=netSizeCol] TD.netSizeCol,
+.netTable[hiddenCols~=netTimeCol] TD[id="netTimeCol"],
+.netTable[hiddenCols~=netTimeCol] TD.netTimeCol {
+    display: none;
+}
+
+/************************************************************************************************/
+
+.netRow {
+    background: LightYellow;
+}
+
+.netRow.loaded {
+    background: #FFFFFF;
+}
+
+.netRow.loaded:hover {
+    background: #EFEFEF;
+}
+
+.netCol {
+    padding: 0;
+    vertical-align: top;
+    border-bottom: 1px solid #EFEFEF;
+    white-space: nowrap;
+    height: 17px;
+}
+
+.netLabel {
+    width: 100%;
+}
+
+.netStatusCol {
+    padding-left: 10px;
+    color: rgb(128, 128, 128);
+}
+
+.responseError > .netStatusCol {
+    color: red;
+}
+
+.netDomainCol {
+    padding-left: 5px;
+}
+
+.netSizeCol {
+    text-align: right;
+    padding-right: 10px;
+}
+
+.netHrefLabel {
+    -moz-box-sizing: padding-box;
+    overflow: hidden;
+    z-index: 10;
+    position: absolute;
+    padding-left: 18px;
+    padding-top: 1px;
+    max-width: 15%;
+    font-weight: bold;
+}
+
+.netFullHrefLabel {
+    display: none;
+    -moz-user-select: none;
+    padding-right: 10px;
+    padding-bottom: 3px;
+    max-width: 100%;
+    background: #FFFFFF;
+    z-index: 200;
+}
+
+.netHrefCol:hover > .netFullHrefLabel {
+    display: block;
+}
+
+.netRow.loaded:hover .netCol > .netFullHrefLabel {
+    background-color: #EFEFEF;
+}
+
+.useA11y .a11yShowFullLabel {
+    display: block;
+    background-image: none !important;
+    border: 1px solid #CBE087;
+    background-color: LightYellow;
+    font-family: Monaco, monospace;
+    color: #000000;
+    font-size: 10px;
+    z-index: 2147483647;
+}
+
+.netSizeLabel {
+    padding-left: 6px;
+}
+
+.netStatusLabel,
+.netDomainLabel,
+.netSizeLabel,
+.netBar {
+    padding: 1px 0 2px 0 !important;
+}
+
+.responseError {
+    color: red;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.hasHeaders .netHrefLabel:hover {
+    cursor: pointer;
+    color: blue;
+    text-decoration: underline;
+}
+
+/************************************************************************************************/
+
+.netLoadingIcon {
+    position: absolute;
+    border: 0;
+    margin-left: 14px;
+    width: 16px;
+    height: 16px;
+    background: transparent no-repeat 0 0;
+    background-image: url(chrome://firebug/skin/loading_16.gif);
+    display:inline-block;
+}
+
+.loaded .netLoadingIcon {
+    display: none;
+}
+
+/************************************************************************************************/
+
+.netBar, .netSummaryBar {
+    position: relative;
+    border-right: 50px solid transparent;
+}
+
+.netResolvingBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    background: #FFFFFF url(chrome://firebug/skin/netBarResolving.gif) repeat-x;
+    z-index:60;
+}
+
+.netConnectingBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    background: #FFFFFF url(chrome://firebug/skin/netBarConnecting.gif) repeat-x;
+    z-index:50;
+}
+
+.netBlockingBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    background: #FFFFFF url(chrome://firebug/skin/netBarWaiting.gif) repeat-x;
+    z-index:40;
+}
+
+.netSendingBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    background: #FFFFFF url(chrome://firebug/skin/netBarSending.gif) repeat-x;
+    z-index:30;
+}
+
+.netWaitingBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    background: #FFFFFF url(chrome://firebug/skin/netBarResponded.gif) repeat-x;
+    z-index:20;
+    min-width: 1px;
+}
+
+.netReceivingBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    background: #38D63B url(chrome://firebug/skin/netBarLoading.gif) repeat-x;
+    z-index:10;
+}
+
+.netWindowLoadBar,
+.netContentLoadBar {
+    position: absolute;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    width: 1px;
+    background-color: red;
+    z-index: 70;
+    opacity: 0.5;
+    display: none;
+    margin-bottom:-1px;
+}
+
+.netContentLoadBar {
+    background-color: Blue;
+}
+
+.netTimeLabel {
+    -moz-box-sizing: padding-box;
+    position: absolute;
+    top: 1px;
+    left: 100%;
+    padding-left: 6px;
+    color: #444444;
+    min-width: 16px;
+}
+
+/*
+ * Timing info tip is reusing net timeline styles to display the same
+ * colors for individual request phases. Notice that the info tip must
+ * respect also loaded and fromCache styles that also modify the
+ * actual color. These are used both on the same element in case
+ * of the tooltip.
+ */
+.loaded .netReceivingBar,
+.loaded.netReceivingBar {
+    background: #B6B6B6 url(chrome://firebug/skin/netBarLoaded.gif) repeat-x;
+    border-color: #B6B6B6;
+}
+
+.fromCache .netReceivingBar,
+.fromCache.netReceivingBar {
+    background: #D6D6D6 url(chrome://firebug/skin/netBarCached.gif) repeat-x;
+    border-color: #D6D6D6;
+}
+
+.netSummaryRow .netTimeLabel,
+.loaded .netTimeLabel {
+    background: transparent;
+}
+
+/************************************************************************************************/
+/* Time Info tip */
+
+.timeInfoTip {
+    width: 150px; 
+    height: 40px
+}
+
+.timeInfoTipBar,
+.timeInfoTipEventBar {
+    position: relative;
+    display: block;
+    margin: 0;
+    opacity: 1;
+    height: 15px;
+    width: 4px;
+}
+
+.timeInfoTipEventBar {
+    width: 1px !important;
+}
+
+.timeInfoTipCell.startTime {
+    padding-right: 8px;
+}
+
+.timeInfoTipCell.elapsedTime {
+    text-align: right;
+    padding-right: 8px;
+}
+
+/************************************************************************************************/
+/* Size Info tip */
+
+.sizeInfoLabelCol {
+    font-weight: bold;
+    padding-right: 10px;
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-size: 11px;
+}
+
+.sizeInfoSizeCol {
+    font-weight: bold;
+}
+
+.sizeInfoDetailCol {
+    color: gray;
+    text-align: right;
+}
+
+.sizeInfoDescCol {
+    font-style: italic;
+}
+
+/************************************************************************************************/
+/* Summary */
+
+.netSummaryRow .netReceivingBar {
+    background: #BBBBBB;
+    border: none;
+}
+
+.netSummaryLabel {
+    color: #222222;
+}
+
+.netSummaryRow {
+    background: #BBBBBB !important;
+    font-weight: bold;
+}
+
+.netSummaryRow .netBar {
+    border-right-color: #BBBBBB;
+}
+
+.netSummaryRow > .netCol {
+    border-top: 1px solid #999999;
+    border-bottom: 2px solid;
+    -moz-border-bottom-colors: #EFEFEF #999999;
+    padding-top: 1px;
+    padding-bottom: 2px;
+}
+
+.netSummaryRow > .netHrefCol:hover {
+    background: transparent !important;
+}
+
+.netCountLabel {
+    padding-left: 18px;
+}
+
+.netTotalSizeCol {
+    text-align: right;
+    padding-right: 10px;
+}
+
+.netTotalTimeCol {
+    text-align: right;
+}
+
+.netCacheSizeLabel {
+    position: absolute;
+    z-index: 1000;
+    left: 0;
+    top: 0;
+}
+
+/************************************************************************************************/
+
+.netLimitRow {
+    background: rgb(255, 255, 225) !important;
+    font-weight:normal;
+    color: black;
+    font-weight:normal;
+}
+
+.netLimitLabel {
+    padding-left: 18px;
+}
+
+.netLimitRow > .netCol {
+    border-bottom: 2px solid;
+    -moz-border-bottom-colors: #EFEFEF #999999;
+    vertical-align: middle !important;
+    padding-top: 2px;
+    padding-bottom: 2px;
+}
+
+.netLimitButton {
+    font-size: 11px;
+    padding-top: 1px;
+    padding-bottom: 1px;
+}
+
+/************************************************************************************************/
+
+.netInfoCol {
+    border-top: 1px solid #EEEEEE;
+    background: url(chrome://firebug/skin/group.gif) repeat-x #FFFFFF;
+}
+
+.netInfoBody {
+    margin: 10px 0 4px 10px;
+}
+
+.netInfoTabs {
+    position: relative;
+    padding-left: 17px;
+}
+
+.netInfoTab {
+    position: relative;
+    top: -3px;
+    margin-top: 10px;
+    padding: 4px 6px;
+    border: 1px solid transparent;
+    border-bottom: none;
+    _border: none;
+    font-weight: bold;
+    color: #565656;
+    cursor: pointer;
+}
+
+/*.netInfoTab:hover {
+    cursor: pointer;
+}*/
+
+/* replaced by .netInfoTabSelected for IE6 support
+.netInfoTab[selected="true"] {
+    cursor: default !important;
+    border: 1px solid #D7D7D7 !important;
+    border-bottom: none !important;
+    -moz-border-radius: 4px 4px 0 0;
+    background-color: #FFFFFF;
+}
+/**/
+.netInfoTabSelected {
+    cursor: default !important;
+    border: 1px solid #D7D7D7 !important;
+    border-bottom: none !important;
+    -moz-border-radius: 4px 4px 0 0;
+    -webkit-border-radius: 4px 4px 0 0;
+    border-radius: 4px 4px 0 0;
+    background-color: #FFFFFF;
+}
+
+.logRow-netInfo.error .netInfoTitle {
+    color: red;
+}
+
+.logRow-netInfo.loading .netInfoResponseText {
+    font-style: italic;
+    color: #888888;
+}
+
+.loading .netInfoResponseHeadersTitle {
+    display: none;
+}
+
+.netInfoResponseSizeLimit {
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    padding-top: 10px;
+    font-size: 11px;
+}
+
+.netInfoText {
+    display: none;
+    margin: 0;
+    border: 1px solid #D7D7D7;
+    border-right: none;
+    padding: 8px;
+    background-color: #FFFFFF;
+    font-family: Monaco, monospace;
+    white-space: pre-wrap;
+    /*overflow-x: auto; HTML is damaged in case of big (2-3MB) responses */
+}
+
+/* replaced by .netInfoTextSelected for IE6 support 
+.netInfoText[selected="true"] {
+    display: block;
+}
+/**/
+.netInfoTextSelected {
+    display: block;
+}
+
+.netInfoParamName {
+    padding-right: 10px;
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-weight: bold;
+    vertical-align: top;
+    text-align: right;
+    white-space: nowrap;
+}
+
+.netInfoPostText .netInfoParamName {
+    width: 1px; /* Google Chrome need this otherwise the first column of 
+                   the post variables table will be larger than expected */
+}
+
+.netInfoParamValue {
+    width: 100%;
+}
+
+.netInfoHeadersText,
+.netInfoPostText,
+.netInfoPutText {
+    padding-top: 0;
+}
+
+.netInfoHeadersGroup,
+.netInfoPostParams,
+.netInfoPostSource {
+    margin-bottom: 4px;
+    border-bottom: 1px solid #D7D7D7;
+    padding-top: 8px;
+    padding-bottom: 2px;
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-weight: bold;
+    color: #565656;
+}
+
+.netInfoPostParamsTable,
+.netInfoPostPartsTable,
+.netInfoPostJSONTable,
+.netInfoPostXMLTable,
+.netInfoPostSourceTable {
+    margin-bottom: 10px;
+    width: 100%;
+}
+
+.netInfoPostContentType {
+    color: #bdbdbd;
+    padding-left: 50px;
+    font-weight: normal;
+}
+
+.netInfoHtmlPreview {
+    border: 0;
+    width: 100%;
+    height:100%;
+}
+
+/************************************************************************************************/
+/* Request & Response Headers */
+
+.netHeadersViewSource {
+    color: #bdbdbd;
+    margin-left: 200px;
+    font-weight: normal;
+}
+
+.netHeadersViewSource:hover {
+    color: blue;
+    cursor: pointer;
+}
+
+/************************************************************************************************/
+
+.netActivationRow,
+.netPageSeparatorRow {
+    background: rgb(229, 229, 229) !important;
+    font-weight: normal;
+    color: black;
+}
+
+.netActivationLabel {
+    background: url(chrome://firebug/skin/infoIcon.png) no-repeat 3px 2px;
+    padding-left: 22px;
+}
+
+/************************************************************************************************/
+
+.netPageSeparatorRow {
+    height: 5px !important;
+}
+
+.netPageSeparatorLabel {
+    padding-left: 22px;
+    height: 5px !important;
+}
+
+.netPageRow {
+    background-color: rgb(255, 255, 255);
+}
+
+.netPageRow:hover {
+    background: #EFEFEF;
+}
+
+.netPageLabel {
+    padding: 1px 0 2px 18px !important;
+    font-weight: bold;
+}
+
+/************************************************************************************************/
+
+.netActivationRow > .netCol {
+    border-bottom: 2px solid;
+    -moz-border-bottom-colors: #EFEFEF #999999;
+    padding-top: 2px;
+    padding-bottom: 3px;
+}
+/*
+.useA11y .panelNode-net .a11yFocus:focus,
+.useA11y .panelNode-net .focusRow:focus {
+    outline-offset: -2px;
+    background-color: #FFFFD6 !important;
+}
+
+.useA11y .panelNode-net .netHeaderCell:focus,
+.useA11y .panelNode-net :focus .netHeaderCell,
+.useA11y .panelNode-net :focus .netReceivingBar,
+.useA11y .netSummaryRow :focus .netBar,
+.useA11y .netSummaryRow:focus .netBar {
+    background-color: #FFFFD6;
+    background-image: none;
+    border-color: #FFFFD6;
+}
+/**/
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* Windows */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+
+
+/************************************************************************************************/
+/* Twisties */
+
+.twisty,
+.logRow-errorMessage > .hasTwisty > .errorTitle,
+.logRow-log > .objectBox-array.hasTwisty,
+.logRow-spy .spyHead .spyTitle,
+.logGroup > .logRow,
+.memberRow.hasChildren > .memberLabelCell > .memberLabel,
+.hasHeaders .netHrefLabel,
+.netPageRow > .netCol > .netPageTitle {
+    background-image: url(tree_open.gif);
+    background-repeat: no-repeat;
+    background-position: 2px 2px;
+    min-height: 12px;
+}
+
+.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
+.logRow-log > .objectBox-array.hasTwisty.opened,
+.logRow-spy.opened .spyHead .spyTitle,
+.logGroup.opened > .logRow,
+.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
+.nodeBox.highlightOpen > .nodeLabel > .twisty,
+.nodeBox.open > .nodeLabel > .twisty,
+.netRow.opened > .netCol > .netHrefLabel,
+.netPageRow.opened > .netCol > .netPageTitle {
+    background-image: url(tree_close.gif);
+}
+
+.twisty {
+    background-position: 4px 4px;
+}
+
+
+
+/************************************************************************************************/
+/* Twisties IE6 */
+
+/* IE6 has problems with > operator, and multiple classes */
+
+* html .logRow-spy .spyHead .spyTitle,
+* html .logGroup .logGroupLabel,
+* html .hasChildren .memberLabelCell .memberLabel,
+* html .hasHeaders .netHrefLabel {
+    background-image: url(tree_open.gif);
+    background-repeat: no-repeat;
+    background-position: 2px 2px;
+}
+
+* html .opened .spyHead .spyTitle,
+* html .opened .logGroupLabel, 
+* html .opened .memberLabelCell .memberLabel {
+    background-image: url(tree_close.gif);
+    background-repeat: no-repeat;
+    background-position: 2px 2px;
+}
+
+
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* Console */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+
+
+/* See license.txt for terms of usage */
+
+.panelNode-console {
+    overflow-x: hidden;
+}
+
+.objectLink {
+    text-decoration: none;
+}
+
+.objectLink:hover {
+    cursor: pointer;
+    text-decoration: underline;
+}
+
+.logRow {
+    position: relative;
+    margin: 0;
+    border-bottom: 1px solid #D7D7D7;
+    padding: 2px 4px 1px 6px;
+    background-color: #FFFFFF;
+    overflow: hidden !important; /* IE need this to avoid disappearing bug with collapsed logs */
+}
+
+.useA11y .logRow:focus {
+    border-bottom: 1px solid #000000 !important;
+    outline: none !important;
+    background-color: #FFFFAD !important;
+}
+
+.useA11y .logRow:focus a.objectLink-sourceLink {
+    background-color: #FFFFAD;
+}
+
+.useA11y .a11yFocus:focus, .useA11y .objectBox:focus {
+    outline: 2px solid #FF9933;
+    background-color: #FFFFAD;
+}
+
+.useA11y .objectBox-null:focus, .useA11y .objectBox-undefined:focus{
+    background-color: #888888 !important;
+}
+
+.useA11y .logGroup.opened > .logRow {
+    border-bottom: 1px solid #ffffff;
+}
+
+.logGroup {
+    background: url(group.gif) repeat-x #FFFFFF;
+    padding: 0 !important;
+    border: none !important;
+}
+
+.logGroupBody {
+    display: none;
+    margin-left: 16px;
+    border-left: 1px solid #D7D7D7;
+    border-top: 1px solid #D7D7D7;
+    background: #FFFFFF;
+}
+
+.logGroup > .logRow {
+    background-color: transparent !important;
+    font-weight: bold;
+}
+
+.logGroup.opened > .logRow {
+    border-bottom: none;
+}
+
+.logGroup.opened > .logGroupBody {
+    display: block;
+}
+
+/*****************************************************************************************/
+
+.logRow-command > .objectBox-text {
+    font-family: Monaco, monospace;
+    color: #0000FF;
+    white-space: pre-wrap;
+}
+
+.logRow-info,
+.logRow-warn,
+.logRow-error,
+.logRow-assert,
+.logRow-warningMessage,
+.logRow-errorMessage {
+    padding-left: 22px;
+    background-repeat: no-repeat;
+    background-position: 4px 2px;
+}
+
+.logRow-assert,
+.logRow-warningMessage,
+.logRow-errorMessage {
+    padding-top: 0;
+    padding-bottom: 0;
+}
+
+.logRow-info,
+.logRow-info .objectLink-sourceLink {
+    background-color: #FFFFFF;
+}
+
+.logRow-warn,
+.logRow-warningMessage,
+.logRow-warn .objectLink-sourceLink,
+.logRow-warningMessage .objectLink-sourceLink {
+    background-color: cyan;
+}
+
+.logRow-error,
+.logRow-assert,
+.logRow-errorMessage,
+.logRow-error .objectLink-sourceLink,
+.logRow-errorMessage .objectLink-sourceLink {
+    background-color: LightYellow;
+}
+
+.logRow-error,
+.logRow-assert,
+.logRow-errorMessage {
+    color: #FF0000;
+}
+
+.logRow-info {
+    /*background-image: url(chrome://firebug/skin/infoIcon.png);*/
+}
+
+.logRow-warn,
+.logRow-warningMessage {
+    /*background-image: url(chrome://firebug/skin/warningIcon.png);*/
+}
+
+.logRow-error,
+.logRow-assert,
+.logRow-errorMessage {
+    /*background-image: url(chrome://firebug/skin/errorIcon.png);*/
+}
+
+/*****************************************************************************************/
+
+.objectBox-string,
+.objectBox-text,
+.objectBox-number,
+.objectLink-element,
+.objectLink-textNode,
+.objectLink-function,
+.objectBox-stackTrace,
+.objectLink-profile {
+    font-family: Monaco, monospace;
+}
+
+.objectBox-string,
+.objectBox-text,
+.objectLink-textNode {
+    white-space: pre-wrap;
+}
+
+.objectBox-number,
+.objectLink-styleRule,
+.objectLink-element,
+.objectLink-textNode {
+    color: #000088;
+}
+
+.objectBox-string {
+    color: #FF0000;
+}
+
+.objectLink-function,
+.objectBox-stackTrace,
+.objectLink-profile  {
+    color: DarkGreen;
+}
+
+.objectBox-null,
+.objectBox-undefined {
+    padding: 0 2px;
+    border: 1px solid #666666;
+    background-color: #888888;
+    color: #FFFFFF;
+}
+
+.objectBox-exception {
+    padding: 0 2px 0 18px;
+    /*background: url(chrome://firebug/skin/errorIcon-sm.png) no-repeat 0 0;*/
+    color: red;
+}
+
+.objectLink-sourceLink {
+    position: absolute;
+    right: 4px;
+    top: 2px;
+    padding-left: 8px;
+    font-family: Lucida Grande, sans-serif;
+    font-weight: bold;
+    color: #0000FF;
+}
+
+/************************************************************************************************/
+
+.errorTitle {
+    margin-top: 0px;
+    margin-bottom: 1px;
+    padding-top: 2px;
+    padding-bottom: 2px;
+}
+
+.errorTrace {
+    margin-left: 17px;
+}
+
+.errorSourceBox {
+    margin: 2px 0;
+}
+
+.errorSource-none {
+    display: none;
+}
+
+.errorSource-syntax > .errorBreak {
+    visibility: hidden;
+}
+
+.errorSource {
+    cursor: pointer;
+    font-family: Monaco, monospace;
+    color: DarkGreen;
+}
+
+.errorSource:hover {
+    text-decoration: underline;
+}
+
+.errorBreak {
+    cursor: pointer;
+    display: none;
+    margin: 0 6px 0 0;
+    width: 13px;
+    height: 14px;
+    vertical-align: bottom;
+    /*background: url(chrome://firebug/skin/breakpoint.png) no-repeat;*/
+    opacity: 0.1;
+}
+
+.hasBreakSwitch .errorBreak {
+    display: inline;
+}
+
+.breakForError .errorBreak {
+    opacity: 1;
+}
+
+.assertDescription {
+    margin: 0;
+}
+
+/************************************************************************************************/
+
+.logRow-profile > .logRow > .objectBox-text {
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    color: #000000;
+}
+
+.logRow-profile > .logRow > .objectBox-text:last-child {
+    color: #555555;
+    font-style: italic;
+}
+
+.logRow-profile.opened > .logRow {
+    padding-bottom: 4px;
+}
+
+.profilerRunning > .logRow {
+    /*background: transparent url(chrome://firebug/skin/loading_16.gif) no-repeat 2px 0 !important;*/
+    padding-left: 22px !important;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.profileSizer {
+    width:100%;
+    overflow-x:auto;
+    overflow-y: scroll;
+}
+
+.profileTable {
+    border-bottom: 1px solid #D7D7D7;
+    padding: 0 0 4px 0;
+}
+
+.profileTable tr[odd="1"] {
+    background-color: #F5F5F5;
+    vertical-align:middle;
+}
+
+.profileTable a {
+    vertical-align:middle;
+}
+
+.profileTable td {
+    padding: 1px 4px 0 4px;
+}
+
+.headerCell {
+    cursor: pointer;
+    -moz-user-select: none;
+    border-bottom: 1px solid #9C9C9C;
+    padding: 0 !important;
+    font-weight: bold;
+    /*background: #BBBBBB url(chrome://firebug/skin/tableHeader.gif) repeat-x;*/
+}
+
+.headerCellBox {
+    padding: 2px 4px;
+    border-left: 1px solid #D9D9D9;
+    border-right: 1px solid #9C9C9C;
+}
+
+.headerCell:hover:active {
+    /*background: #959595 url(chrome://firebug/skin/tableHeaderActive.gif) repeat-x;*/
+}
+
+.headerSorted {
+    /*background: #7D93B2 url(chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;*/
+}
+
+.headerSorted > .headerCellBox {
+    border-right-color: #6B7C93;
+    /*background: url(chrome://firebug/skin/arrowDown.png) no-repeat right;*/
+}
+
+.headerSorted.sortedAscending > .headerCellBox {
+    /*background-image: url(chrome://firebug/skin/arrowUp.png);*/
+}
+
+.headerSorted:hover:active {
+    /*background: #536B90 url(chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;*/
+}
+
+.linkCell {
+    text-align: right;
+}
+
+.linkCell > .objectLink-sourceLink {
+    position: static;
+}
+
+/*****************************************************************************************/
+
+.logRow-stackTrace {
+    padding-top: 0;
+    background: #f8f8f8;
+}
+
+.logRow-stackTrace > .objectBox-stackFrame {
+    position: relative;
+    padding-top: 2px;
+}
+
+/************************************************************************************************/
+
+.objectLink-object {
+    font-family: Lucida Grande, sans-serif;
+    font-weight: bold;
+    color: DarkGreen;
+    white-space: pre-wrap;
+}
+
+/* xxxpedro reps object representation .................................... */
+.objectProp-object {
+    color: DarkGreen;
+}
+
+.objectProps {
+    color: #000;
+    font-weight: normal;
+}
+
+.objectPropName {
+    /*font-style: italic;*/
+    color: #777;
+}
+
+/*
+.objectProps .objectProp-string,
+.objectProps .objectProp-number,
+.objectProps .objectProp-object
+{
+    font-style: italic;
+}
+/**/
+
+.objectProps .objectProp-string
+{
+    /*font-family: Monaco, monospace;*/
+    color: #f55;
+}
+.objectProps .objectProp-number
+{
+    /*font-family: Monaco, monospace;*/
+    color: #55a;
+}
+.objectProps .objectProp-object
+{
+    /*font-family: Lucida Grande,sans-serif;*/
+    color: #585;
+}
+/* xxxpedro reps object representation .................................... */
+
+/************************************************************************************************/
+
+.selectorTag,
+.selectorId,
+.selectorClass {
+    font-family: Monaco, monospace;
+    font-weight: normal;
+}
+
+.selectorTag {
+    color: #0000FF;
+}
+
+.selectorId {
+    color: DarkBlue;
+}
+
+.selectorClass {
+    color: red;
+}
+
+.selectorHidden > .selectorTag {
+    color: #5F82D9;
+}
+
+.selectorHidden > .selectorId {
+    color: #888888;
+}
+
+.selectorHidden > .selectorClass {
+    color: #D86060;
+}
+
+.selectorValue {
+    font-family: Lucida Grande, sans-serif;
+    font-style: italic;
+    color: #555555;
+}
+
+/*****************************************************************************************/
+
+.panelNode.searching .logRow {
+    display: none;
+}
+
+.logRow.matched {
+    display: block !important;
+}
+
+.logRow.matching {
+    position: absolute;
+    left: -1000px;
+    top: -1000px;
+    max-width: 0;
+    max-height: 0;
+    overflow: hidden;
+}
+
+/*****************************************************************************************/
+
+.objectLeftBrace,
+.objectRightBrace,
+.objectEqual,
+.objectComma,
+.arrayLeftBracket,
+.arrayRightBracket,
+.arrayComma {
+    font-family: Monaco, monospace;
+}
+
+.objectLeftBrace,
+.objectRightBrace,
+.arrayLeftBracket,
+.arrayRightBracket {
+    font-weight: bold;
+}
+
+.objectLeftBrace,
+.arrayLeftBracket {
+    margin-right: 4px;
+}
+
+.objectRightBrace,
+.arrayRightBracket {
+    margin-left: 4px;
+}
+
+/*****************************************************************************************/
+
+.logRow-dir {
+    padding: 0;
+}
+
+/************************************************************************************************/
+
+/*
+.logRow-errorMessage > .hasTwisty > .errorTitle,
+.logRow-spy .spyHead .spyTitle,
+.logGroup > .logRow 
+*/
+.logRow-errorMessage .hasTwisty .errorTitle,
+.logRow-spy .spyHead .spyTitle,
+.logGroup .logRow {
+    cursor: pointer;
+    padding-left: 18px;
+    background-repeat: no-repeat;
+    background-position: 3px 3px;
+}
+
+.logRow-errorMessage > .hasTwisty > .errorTitle {
+    background-position: 2px 3px;
+}
+
+.logRow-errorMessage > .hasTwisty > .errorTitle:hover,
+.logRow-spy .spyHead .spyTitle:hover,
+.logGroup > .logRow:hover {
+    text-decoration: underline;
+}
+
+/*****************************************************************************************/
+
+.logRow-spy {
+    padding: 0 !important;
+}
+
+.logRow-spy,
+.logRow-spy .objectLink-sourceLink {
+    background: url(group.gif) repeat-x #FFFFFF;
+    padding-right: 4px;
+    right: 0;
+}
+
+.logRow-spy.opened {
+    padding-bottom: 4px;
+    border-bottom: none;
+}
+
+.spyTitle {
+    color: #000000;
+    font-weight: bold;
+    -moz-box-sizing: padding-box;
+    overflow: hidden;
+    z-index: 100;
+    padding-left: 18px;
+}
+
+.spyCol {
+    padding: 0;
+    white-space: nowrap;
+    height: 16px;
+}
+
+.spyTitleCol:hover > .objectLink-sourceLink,
+.spyTitleCol:hover > .spyTime,
+.spyTitleCol:hover > .spyStatus,
+.spyTitleCol:hover > .spyTitle {
+    display: none;
+}
+
+.spyFullTitle {
+    display: none;
+    -moz-user-select: none;
+    max-width: 100%;
+    background-color: Transparent;
+}
+
+.spyTitleCol:hover > .spyFullTitle {
+    display: block;
+}
+
+.spyStatus {
+    padding-left: 10px;
+    color: rgb(128, 128, 128);
+}
+
+.spyTime {
+    margin-left:4px;
+    margin-right:4px;
+    color: rgb(128, 128, 128);
+}
+
+.spyIcon {
+    margin-right: 4px;
+    margin-left: 4px;
+    width: 16px;
+    height: 16px;
+    vertical-align: middle;
+    background: transparent no-repeat 0 0;
+    display: none;
+}
+
+.loading .spyHead .spyRow .spyIcon {
+    background-image: url(loading_16.gif);
+    display: block;
+}
+
+.logRow-spy.loaded:not(.error) .spyHead .spyRow .spyIcon {
+    width: 0;
+    margin: 0;
+}
+
+.logRow-spy.error .spyHead .spyRow .spyIcon {
+    background-image: url(errorIcon-sm.png);
+    display: block;
+    background-position: 2px 2px;
+}
+
+.logRow-spy .spyHead .netInfoBody {
+    display: none;
+}
+
+.logRow-spy.opened .spyHead .netInfoBody {
+    margin-top: 10px;
+    display: block;
+}
+
+.logRow-spy.error .spyTitle,
+.logRow-spy.error .spyStatus,
+.logRow-spy.error .spyTime {
+    color: red;
+}
+
+.logRow-spy.loading .spyResponseText {
+    font-style: italic;
+    color: #888888;
+}
+
+/************************************************************************************************/
+
+.caption {
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-weight: bold;
+    color:  #444444;
+}
+
+.warning {
+    padding: 10px;
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-weight: bold;
+    color:  #888888;
+}
+
+
+
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* DOM */
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+
+
+/* See license.txt for terms of usage */
+
+.panelNode-dom {
+    overflow-x: hidden !important;
+}
+
+.domTable {
+    font-size: 1em;
+    width: 100%;
+    table-layout: fixed;
+    background: #fff;
+}
+
+.domTableIE {
+    width: auto;
+}
+
+.memberLabelCell {
+    padding: 2px 0 2px 0;
+    vertical-align: top;
+}
+
+.memberValueCell {
+    padding: 1px 0 1px 5px;
+    display: block;
+    overflow: hidden;
+}
+
+.memberLabel {
+    display: block;
+    cursor: default;
+    -moz-user-select:  none;
+    overflow: hidden;
+    /*position: absolute;*/
+    padding-left: 18px;
+    /*max-width: 30%;*/
+    /*white-space: nowrap;*/
+    background-color: #FFFFFF;
+    text-decoration: none;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.memberRow.hasChildren .memberLabelCell .memberLabel:hover {
+    cursor: pointer;
+    color: blue;
+    text-decoration: underline;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.userLabel {
+    color: #000000;
+    font-weight: bold;
+}
+
+.userClassLabel {
+    color: #E90000;
+    font-weight: bold;
+}
+
+.userFunctionLabel {
+    color: #025E2A;
+    font-weight: bold;
+}
+
+.domLabel {
+    color: #000000;
+}
+
+.domFunctionLabel {
+    color: #025E2A;
+}
+
+.ordinalLabel {
+    color: SlateBlue;
+    font-weight: bold;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+.scopesRow {
+    padding: 2px 18px;
+    background-color: LightYellow;
+    border-bottom: 5px solid #BEBEBE;
+    color: #666666;
+}
+.scopesLabel {
+    background-color:  LightYellow;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.watchEditCell {
+    padding: 2px 18px;
+    background-color: LightYellow;
+    border-bottom: 1px solid #BEBEBE;
+    color: #666666;
+}
+
+.editor-watchNewRow,
+.editor-memberRow {
+    font-family: Monaco, monospace !important;
+}
+
+.editor-memberRow {
+    padding: 1px 0 !important;
+}
+
+.editor-watchRow {
+    padding-bottom: 0 !important;
+}
+
+.watchRow > .memberLabelCell {
+    font-family: Monaco, monospace;
+    padding-top: 1px;
+    padding-bottom: 1px;
+}
+
+.watchRow > .memberLabelCell > .memberLabel {
+    background-color: transparent;
+}
+
+.watchRow > .memberValueCell {
+    padding-top: 2px;
+    padding-bottom: 2px;
+}
+
+.watchRow > .memberLabelCell,
+.watchRow > .memberValueCell {
+    background-color: #F5F5F5;
+    border-bottom: 1px solid #BEBEBE;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.watchToolbox {
+    z-index: 2147483647;
+    position: absolute;
+    right: 0;
+    padding: 1px 2px;
+}
+
+
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/*************************************************************************************************/
+/* FROM ORIGINAL FIREBUG */
+
+
+
+
+/************************************************************************************************
+ CSS Not organized
+*************************************************************************************************/
+#fbConsole {
+    overflow-x: hidden !important;
+}
+
+#fbCSS {
+    font: 1em Monaco, monospace;
+    padding: 0 7px;
+}
+
+#fbstylesheetButtons select, #fbScriptButtons select {
+    font: 11px Lucida Grande, Tahoma, sans-serif;
+    margin-top: 1px;
+    padding-left: 3px;
+    background: #fafafa;
+    border: 1px inset #fff;
+    width: 220px;
+    outline: none;
+}
+
+.Selector { margin-top:10px }
+.CSSItem {margin-left: 4% }
+.CSSText { padding-left:20px; }
+.CSSProperty { color:#005500; }
+.CSSValue { padding-left:5px; color:#000088; }
+
+
+/************************************************************************************************
+ Not organized
+*************************************************************************************************/
+
+#fbHTMLStatusBar {
+    display: inline;
+}
+
+.fbToolbarButtons {
+    display: none;
+}
+
+.fbStatusSeparator{
+    display: block;
+    float: left;
+    padding-top: 4px;
+}
+
+#fbStatusBarBox {
+    display: none;
+}
+
+#fbToolbarContent {
+    display: block;
+    position: absolute;
+    _position: absolute;
+    top: 0;
+    padding-top: 4px;
+    height: 23px;
+    clip: rect(0, 2048px, 27px, 0);
+}
+
+.fbTabMenuTarget {
+    display: none !important;
+    float: left;
+    width: 10px;
+    height: 10px;
+    margin-top: 6px;
+    background: url(tabMenuTarget.png);   
+}
+
+.fbTabMenuTarget:hover {
+    background: url(tabMenuTargetHover.png);   
+}
+
+.fbShadow {
+    float: left;
+    background: url(shadowAlpha.png) no-repeat bottom right !important;
+    background: url(shadow2.gif) no-repeat bottom right;
+    margin: 10px 0 0 10px !important;
+    margin: 10px 0 0 5px;
+}
+
+.fbShadowContent {
+    display: block;
+    position: relative;
+    background-color: #fff;
+    border: 1px solid #a9a9a9;
+    top: -6px;
+    left: -6px;
+}
+
+.fbMenu {
+    display: none;
+    position: absolute;
+    font-size: 11px;
+    line-height: 13px;
+    z-index: 2147483647;
+}
+
+.fbMenuContent {
+    padding: 2px;
+}
+
+.fbMenuSeparator {
+    display: block;
+    position: relative;
+    padding: 1px 18px 0;
+    text-decoration: none;
+    color: #000;
+    cursor: default;    
+    background: #ACA899;
+    margin: 4px 0;
+}
+
+.fbMenuOption
+{
+    display: block;
+    position: relative;
+    padding: 2px 18px;
+    text-decoration: none;
+    color: #000;
+    cursor: default;
+}
+
+.fbMenuOption:hover
+{
+    color: #fff;
+    background: #316AC5;
+}
+
+.fbMenuGroup {
+    background: transparent url(tabMenuPin.png) no-repeat right 0;
+}
+
+.fbMenuGroup:hover {
+    background: #316AC5 url(tabMenuPin.png) no-repeat right -17px;
+}
+
+.fbMenuGroupSelected {
+    color: #fff;
+    background: #316AC5 url(tabMenuPin.png) no-repeat right -17px;
+}
+
+.fbMenuChecked  {
+    background: transparent url(tabMenuCheckbox.png) no-repeat 4px 0;
+}
+
+.fbMenuChecked:hover {
+    background: #316AC5 url(tabMenuCheckbox.png) no-repeat 4px -17px;
+}
+
+.fbMenuRadioSelected {
+    background: transparent url(tabMenuRadio.png) no-repeat 4px 0;
+}
+
+.fbMenuRadioSelected:hover {
+    background: #316AC5 url(tabMenuRadio.png) no-repeat 4px -17px;
+}
+
+.fbMenuShortcut {
+    padding-right: 85px; 
+}
+
+.fbMenuShortcutKey {
+    position: absolute;
+    right: 0;
+    top: 2px;
+    width: 77px;
+}
+
+#fbFirebugMenu {
+    top: 22px;
+    left: 0;
+}
+
+.fbMenuDisabled {
+    color: #ACA899 !important;
+}
+
+#fbFirebugSettingsMenu {
+    left: 245px;
+    top: 99px;
+}
+
+#fbConsoleMenu {
+    top: 42px;
+    left: 48px;
+}
+
+.fbIconButton {
+    display: block;
+}
+
+.fbIconButton {
+    display: block;
+}
+
+.fbIconButton {
+    display: block;
+    float: left;
+    height: 20px;
+    width: 20px;
+    color: #000;
+    margin-right: 2px;
+    text-decoration: none;
+    cursor: default;
+}
+
+.fbIconButton:hover {
+    position: relative;
+    top: -1px;
+    left: -1px;
+    margin-right: 0;
+    _margin-right: 1px;
+    color: #333;
+    border: 1px solid #fff;
+    border-bottom: 1px solid #bbb;
+    border-right: 1px solid #bbb;
+}
+
+.fbIconPressed {
+    position: relative;
+    margin-right: 0;
+    _margin-right: 1px;
+    top: 0 !important;
+    left: 0 !important;
+    height: 19px;
+    color: #333 !important;
+    border: 1px solid #bbb !important;
+    border-bottom: 1px solid #cfcfcf !important;
+    border-right: 1px solid #ddd !important;
+}
+
+
+
+/************************************************************************************************
+ Error Popup
+*************************************************************************************************/
+#fbErrorPopup {
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    height: 19px;
+    width: 75px;
+    background: url(sprite.png) #f1f2ee 0 0;
+    z-index: 999;
+}
+
+#fbErrorPopupContent {
+    position: absolute;
+    right: 0;
+    top: 1px;
+    height: 18px;
+    width: 75px;
+    _width: 74px;
+    border-left: 1px solid #aca899;
+}
+
+#fbErrorIndicator {
+    position: absolute;
+    top: 2px;
+    right: 5px;
+}
+
+
+
+
+
+
+
+
+
+
+.fbBtnInspectActive {
+    background: #aaa;
+    color: #fff !important;
+}
+
+/************************************************************************************************
+ General
+*************************************************************************************************/
+.fbBody {
+    margin: 0;
+    padding: 0;
+    overflow: hidden;
+    
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-size: 11px;
+    background: #fff;
+}
+
+.clear {
+    clear: both;
+}
+
+/************************************************************************************************
+ Mini Chrome
+*************************************************************************************************/
+#fbMiniChrome {
+    display: none;
+    right: 0;
+    height: 27px;
+    background: url(sprite.png) #f1f2ee 0 0;
+    margin-left: 1px;
+}
+
+#fbMiniContent {
+    display: block;
+    position: relative;
+    left: -1px;
+    right: 0;
+    top: 1px;
+    height: 25px;
+    border-left: 1px solid #aca899;
+}
+
+#fbToolbarSearch {
+    float: right;
+    border: 1px solid #ccc;
+    margin: 0 5px 0 0;
+    background: #fff url(search.png) no-repeat 4px 2px !important;
+    background: #fff url(search.gif) no-repeat 4px 2px;
+    padding-left: 20px;    
+    font-size: 11px;
+}
+
+#fbToolbarErrors {
+    float: right;
+    margin: 1px 4px 0 0;
+    font-size: 11px;
+}
+
+#fbLeftToolbarErrors {
+    float: left;
+    margin: 7px 0px 0 5px;
+    font-size: 11px;
+}
+
+.fbErrors {
+    padding-left: 20px;
+    height: 14px;
+    background: url(errorIcon.png) no-repeat !important;
+    background: url(errorIcon.gif) no-repeat;
+    color: #f00;
+    font-weight: bold;    
+}
+
+#fbMiniErrors {
+    display: inline;
+    display: none;
+    float: right;
+    margin: 5px 2px 0 5px;
+}
+
+#fbMiniIcon {
+    float: right;
+    margin: 3px 4px 0;
+    height: 20px;
+    width: 20px;
+    float: right;    
+    background: url(sprite.png) 0 -135px;
+    cursor: pointer;
+}
+
+
+/************************************************************************************************
+ Master Layout
+*************************************************************************************************/
+#fbChrome {
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-size: 11px;
+    position: absolute;
+    _position: static;
+    top: 0;
+    left: 0;
+    height: 100%;
+    width: 100%;
+    border-collapse: collapse;
+    border-spacing: 0;
+    background: #fff;
+    overflow: hidden;
+}
+
+#fbChrome > tbody > tr > td {
+    padding: 0;
+}
+
+#fbTop {
+    height: 49px;
+}
+
+#fbToolbar {
+    background: url(sprite.png) #f1f2ee 0 0;
+    height: 27px;
+    font-size: 11px;
+    line-height: 13px;
+}
+
+#fbPanelBarBox {
+    background: url(sprite.png) #dbd9c9 0 -27px;
+    height: 22px;
+}
+
+#fbContent {
+    height: 100%;
+    vertical-align: top;
+}
+
+#fbBottom {
+    height: 18px;
+    background: #fff;
+}
+
+/************************************************************************************************
+ Sub-Layout 
+*************************************************************************************************/
+
+/* fbToolbar 
+*************************************************************************************************/
+#fbToolbarIcon {
+    float: left;
+    padding: 0 5px 0;
+}
+
+#fbToolbarIcon a {
+    background: url(sprite.png) 0 -135px;
+}
+
+#fbToolbarButtons {
+    padding: 0 2px 0 5px;
+}
+
+#fbToolbarButtons {
+    padding: 0 2px 0 5px;
+}
+/*
+#fbStatusBarBox a {
+    text-decoration: none;
+    display: block;
+    float: left;
+    color: #000;
+    padding: 4px 5px;
+    margin: 0 0 0 1px;
+    cursor: default;
+}
+
+#fbStatusBarBox a:hover {
+    color: #333;
+    padding: 3px 4px;
+    border: 1px solid #fff;
+    border-bottom: 1px solid #bbb;
+    border-right: 1px solid #bbb;
+}
+/**/
+
+.fbButton {
+    text-decoration: none;
+    display: block;
+    float: left;
+    color: #000;
+    padding: 4px 6px 4px 7px;
+    cursor: default;
+}
+
+.fbButton:hover {
+    color: #333;
+    background: #f5f5ef url(buttonBg.png);
+    padding: 3px 5px 3px 6px;
+    border: 1px solid #fff;
+    border-bottom: 1px solid #bbb;
+    border-right: 1px solid #bbb;
+}
+
+.fbBtnPressed {
+    background: #e3e3db url(buttonBgHover.png) !important;
+    padding: 3px 4px 2px 6px !important;
+    margin: 1px 0 0 1px !important;
+    border: 1px solid #ACA899 !important;
+    border-color: #ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;
+}
+
+#fbStatusBarBox {
+    top: 4px;
+    cursor: default;    
+}
+
+.fbToolbarSeparator {
+    overflow: hidden;
+    border: 1px solid;
+    border-color: transparent #fff transparent #777;
+    _border-color: #eee #fff #eee #777;
+    height: 7px;
+    margin: 6px 3px;
+    float: left;
+}
+
+.fbBtnSelected {
+    font-weight: bold;
+}
+
+.fbStatusBar {
+    color: #aca899;
+}
+
+.fbStatusBar a {
+    text-decoration: none;
+    color: black;
+}
+
+.fbStatusBar a:hover {
+    color: blue;
+    cursor: pointer;    
+}
+
+
+#fbWindowButtons {
+    position: absolute;
+    white-space: nowrap;
+    right: 0;
+    top: 0;
+    height: 17px;
+    width: 48px;
+    padding: 5px;
+    z-index: 6;
+    background: url(sprite.png) #f1f2ee 0 0;
+}
+
+/* fbPanelBarBox
+*************************************************************************************************/
+
+#fbPanelBar1 {
+    width: 1024px; /* fixed width to avoid tabs breaking line */
+    z-index: 8;
+    left: 0;
+    white-space: nowrap;
+    background: url(sprite.png) #dbd9c9 0 -27px;
+    position: absolute;
+    left: 4px;
+}
+
+#fbPanelBar2Box {
+    background: url(sprite.png) #dbd9c9 0 -27px;
+    position: absolute;
+    height: 22px;
+    width: 300px; /* fixed width to avoid tabs breaking line */
+    z-index: 9;
+    right: 0;
+}
+
+#fbPanelBar2 {
+    position: absolute;
+    width: 290px; /* fixed width to avoid tabs breaking line */
+    height: 22px;
+    padding-left: 4px;
+}
+
+/* body 
+*************************************************************************************************/
+.fbPanel {
+    display: none;
+}
+
+#fbPanelBox1, #fbPanelBox2 {
+    max-height: inherit;
+    height: 100%;
+    font-size: 1em;
+}
+
+#fbPanelBox2 {
+    background: #fff;
+}
+
+#fbPanelBox2 {
+    width: 300px;
+    background: #fff;
+}
+
+#fbPanel2 {
+    margin-left: 6px;
+    background: #fff;
+}
+
+#fbLargeCommandLine {
+    display: none;
+    position: absolute;
+    z-index: 9;
+    top: 27px;
+    right: 0;
+    width: 294px;
+    height: 201px;
+    border-width: 0;
+    margin: 0;
+    padding: 2px 0 0 2px;
+    resize: none;
+    outline: none;
+    font-size: 11px;
+    overflow: auto;
+    border-top: 1px solid #B9B7AF;
+    _right: -1px;
+    _border-left: 1px solid #fff;
+}
+
+#fbLargeCommandButtons {
+    display: none;
+    background: #ECE9D8;
+    bottom: 0;
+    right: 0;
+    width: 294px;
+    height: 21px;
+    padding-top: 1px;
+    position: fixed;
+    border-top: 1px solid #ACA899;
+    z-index: 9;
+}
+
+#fbSmallCommandLineIcon {
+    background: url(down.png) no-repeat;
+    position: absolute;
+    right: 2px;
+    bottom: 3px;
+    
+    z-index: 99;
+}
+
+#fbSmallCommandLineIcon:hover {
+    background: url(downHover.png) no-repeat;
+}
+
+.hide {
+    overflow: hidden !important;
+    position: fixed !important;
+    display: none !important;
+    visibility: hidden !important;
+}
+
+/* fbBottom 
+*************************************************************************************************/
+
+#fbCommand {
+    height: 18px;
+}
+
+#fbCommandBox {
+    position: fixed;
+    _position: absolute;
+    width: 100%;
+    height: 18px;
+    bottom: 0;
+    overflow: hidden;
+    z-index: 9;
+    background: #fff;
+    border: 0;
+    border-top: 1px solid #ccc;
+}
+
+#fbCommandIcon {
+    position: absolute;
+    color: #00f;
+    top: 2px;
+    left: 6px;
+    display: inline;
+    font: 11px Monaco, monospace;
+    z-index: 10;
+}
+
+#fbCommandLine {
+    position: absolute;
+    width: 100%;
+    top: 0;
+    left: 0;
+    border: 0;
+    margin: 0;
+    padding: 2px 0 2px 32px;
+    font: 11px Monaco, monospace;
+    z-index: 9;
+    outline: none;
+}
+
+#fbLargeCommandLineIcon {
+    background: url(up.png) no-repeat;
+    position: absolute;
+    right: 1px;
+    bottom: 1px;
+    z-index: 10;
+}
+
+#fbLargeCommandLineIcon:hover {
+    background: url(upHover.png) no-repeat;
+}
+
+div.fbFitHeight {
+    overflow: auto;
+    position: relative;
+}
+
+
+/************************************************************************************************
+ Layout Controls
+*************************************************************************************************/
+
+/* fbToolbar buttons 
+*************************************************************************************************/
+.fbSmallButton {
+    overflow: hidden;
+    width: 16px;
+    height: 16px;
+    display: block;
+    text-decoration: none;
+    cursor: default;
+}
+
+#fbWindowButtons .fbSmallButton {
+    float: right;
+}
+
+#fbWindow_btClose {
+    background: url(min.png);
+}
+
+#fbWindow_btClose:hover {
+    background: url(minHover.png);
+}
+
+#fbWindow_btDetach {
+    background: url(detach.png);
+}
+
+#fbWindow_btDetach:hover {
+    background: url(detachHover.png);
+}
+
+#fbWindow_btDeactivate {
+    background: url(off.png);
+}
+
+#fbWindow_btDeactivate:hover {
+    background: url(offHover.png);
+}
+
+
+/* fbPanelBarBox tabs 
+*************************************************************************************************/
+.fbTab {
+    text-decoration: none;
+    display: none;
+    float: left;
+    width: auto;
+    float: left;
+    cursor: default;
+    font-family: Lucida Grande, Tahoma, sans-serif;
+    font-size: 11px;
+    line-height: 13px;
+    font-weight: bold;
+    height: 22px;
+    color: #565656;
+}
+
+.fbPanelBar span {
+    /*display: block; TODO: safe to remove this? */
+    float: left;
+}
+
+.fbPanelBar .fbTabL,.fbPanelBar .fbTabR {
+    height: 22px;
+    width: 8px;
+}
+
+.fbPanelBar .fbTabText {
+    padding: 4px 1px 0;
+}
+
+a.fbTab:hover {
+    background: url(sprite.png) 0 -73px;
+}
+
+a.fbTab:hover .fbTabL {
+    background: url(sprite.png) -16px -96px;
+}
+
+a.fbTab:hover .fbTabR {
+    background: url(sprite.png) -24px -96px;
+}
+
+.fbSelectedTab {
+    background: url(sprite.png) #f1f2ee 0 -50px !important;
+    color: #000;
+}
+
+.fbSelectedTab .fbTabL {
+    background: url(sprite.png) 0 -96px !important;
+}
+
+.fbSelectedTab .fbTabR {
+    background: url(sprite.png) -8px -96px !important;
+}
+
+/* splitters 
+*************************************************************************************************/
+#fbHSplitter {
+    position: fixed;
+    _position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 5px;
+    overflow: hidden;
+    cursor: n-resize !important;
+    background: url(pixel_transparent.gif);
+    z-index: 9;
+}
+
+#fbHSplitter.fbOnMovingHSplitter {
+    height: 100%;
+    z-index: 100;
+}
+
+.fbVSplitter {
+    background: #ece9d8;
+    color: #000;
+    border: 1px solid #716f64;
+    border-width: 0 1px;
+    border-left-color: #aca899;
+    width: 4px;
+    cursor: e-resize;
+    overflow: hidden;
+    right: 294px;
+    text-decoration: none;
+    z-index: 10;
+    position: absolute;
+    height: 100%;
+    top: 27px;
+}
+
+/************************************************************************************************/
+div.lineNo {
+    font: 1em/1.4545em Monaco, monospace;
+    position: relative;
+    float: left;
+    top: 0;
+    left: 0;
+    margin: 0 5px 0 0;
+    padding: 0 5px 0 10px;
+    background: #eee;
+    color: #888;
+    border-right: 1px solid #ccc;
+    text-align: right;
+}
+
+.sourceBox {
+    position: absolute;
+}
+
+.sourceCode {
+    font: 1em Monaco, monospace;
+    overflow: hidden;
+    white-space: pre;
+    display: inline;
+}
+
+/************************************************************************************************/
+.nodeControl {
+    margin-top: 3px;
+    margin-left: -14px;
+    float: left;
+    width: 9px;
+    height: 9px;
+    overflow: hidden;
+    cursor: default;
+    background: url(tree_open.gif);
+    _float: none;
+    _display: inline;
+    _position: absolute;
+}
+
+div.nodeMaximized {
+    background: url(tree_close.gif);
+}
+
+div.objectBox-element {
+    padding: 1px 3px;
+}
+.objectBox-selector{
+    cursor: default;
+}
+
+.selectedElement{
+    background: highlight;
+    /* background: url(roundCorner.svg); Opera */
+    color: #fff !important;
+}
+.selectedElement span{
+    color: #fff !important;
+}
+
+/* IE6 need this hack */
+* html .selectedElement {
+    position: relative;
+}
+
+/* Webkit CSS Hack - bug in "highlight" named color */ 
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+    .selectedElement{
+      background: #316AC5;
+      color: #fff !important;
+    }
+}
+
+/************************************************************************************************/
+/************************************************************************************************/
+.logRow * {
+    font-size: 1em;
+}
+
+/* TODO: remove this? */
+/* TODO: xxxpedro - IE need this in windowless mode (cnn.com) check if the issue is related to 
+position. if so, override it at chrome.js initialization when creating the div */
+.logRow {
+    position: relative;
+    border-bottom: 1px solid #D7D7D7;
+    padding: 2px 4px 1px 6px;
+    zbackground-color: #FFFFFF;
+}
+/**/
+
+.logRow-command {
+    font-family: Monaco, monospace;
+    color: blue;
+}
+
+.objectBox-string,
+.objectBox-text,
+.objectBox-number,
+.objectBox-function,
+.objectLink-element,
+.objectLink-textNode,
+.objectLink-function,
+.objectBox-stackTrace,
+.objectLink-profile {
+    font-family: Monaco, monospace;
+}
+
+.objectBox-null {
+    padding: 0 2px;
+    border: 1px solid #666666;
+    background-color: #888888;
+    color: #FFFFFF;
+}
+
+.objectBox-string {
+    color: red;
+    
+    /* TODO: xxxpedro make long strings break line */
+    /*white-space: pre; */ 
+}
+
+.objectBox-number {
+    color: #000088;
+}
+
+.objectBox-function {
+    color: DarkGreen;
+}
+
+.objectBox-object {
+    color: DarkGreen;
+    font-weight: bold;
+    font-family: Lucida Grande, sans-serif;
+}
+
+.objectBox-array {
+    color: #000;
+}
+
+/************************************************************************************************/
+.logRow-info,.logRow-error,.logRow-warn {
+    background: #fff no-repeat 2px 2px;
+    padding-left: 20px;
+    padding-bottom: 3px;
+}
+
+.logRow-info {
+    background-image: url(infoIcon.png) !important;
+    background-image: url(infoIcon.gif);
+}
+
+.logRow-warn {
+    background-color: cyan;
+    background-image: url(warningIcon.png) !important;
+    background-image: url(warningIcon.gif);
+}
+
+.logRow-error {
+    background-color: LightYellow;
+    background-image: url(errorIcon.png) !important;
+    background-image: url(errorIcon.gif);
+    color: #f00;
+}
+
+.errorMessage {
+    vertical-align: top;
+    color: #f00;
+}
+
+.objectBox-sourceLink {
+    position: absolute;
+    right: 4px;
+    top: 2px;
+    padding-left: 8px;
+    font-family: Lucida Grande, sans-serif;
+    font-weight: bold;
+    color: #0000FF;
+}
+
+/************************************************************************************************/
+/*
+//TODO: remove this when console2 is finished
+*/
+/*
+.logRow-group {
+    background: #EEEEEE;
+    border-bottom: none;
+}
+
+.logGroup {
+    background: #EEEEEE;
+}
+
+.logGroupBox {
+    margin-left: 24px;
+    border-top: 1px solid #D7D7D7;
+    border-left: 1px solid #D7D7D7;
+}/**/
+
+/************************************************************************************************/
+.selectorTag,.selectorId,.selectorClass {
+    font-family: Monaco, monospace;
+    font-weight: normal;
+}
+
+.selectorTag {
+    color: #0000FF;
+}
+
+.selectorId {
+    color: DarkBlue;
+}
+
+.selectorClass {
+    color: red;
+}
+
+/************************************************************************************************/
+.objectBox-element {
+    font-family: Monaco, monospace;
+    color: #000088;
+}
+
+.nodeChildren {
+    padding-left: 26px;
+}
+
+.nodeTag {
+    color: blue;
+    cursor: pointer;
+}
+
+.nodeValue {
+    color: #FF0000;
+    font-weight: normal;
+}
+
+.nodeText,.nodeComment {
+    margin: 0 2px;
+    vertical-align: top;
+}
+
+.nodeText {
+    color: #333333;
+    font-family: Monaco, monospace;
+}
+
+.nodeComment {
+    color: DarkGreen;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeHidden, .nodeHidden * {
+    color: #888888;
+}
+
+.nodeHidden .nodeTag {
+    color: #5F82D9;
+}
+
+.nodeHidden .nodeValue {
+    color: #D86060;
+}
+
+.selectedElement .nodeHidden, .selectedElement .nodeHidden * {
+    color: SkyBlue !important;
+}
+
+
+/************************************************************************************************/
+.log-object {
+    /*
+    _position: relative;
+    _height: 100%;
+    /**/
+}
+
+.property {
+    position: relative;
+    clear: both;
+    height: 15px;
+}
+
+.propertyNameCell {
+    vertical-align: top;
+    float: left;
+    width: 28%;
+    position: absolute;
+    left: 0;
+    z-index: 0;
+}
+
+.propertyValueCell {
+    float: right;
+    width: 68%;
+    background: #fff;
+    position: absolute;
+    padding-left: 5px;
+    display: table-cell;
+    right: 0;
+    z-index: 1;
+    /*
+    _position: relative;
+    /**/
+}
+
+.propertyName {
+    font-weight: bold;
+}
+
+.FirebugPopup {
+    height: 100% !important;
+}
+
+.FirebugPopup #fbWindowButtons {
+    display: none !important;
+}
+
+.FirebugPopup #fbHSplitter {
+    display: none !important;
+}
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.html b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.html
new file mode 100644
index 0000000..aa07809
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8">
+<title>Firebug Lite</title>
+<!-- An empty script to avoid FOUC when loading the stylesheet -->
+<script type="text/javascript"></script>
+<style type="text/css" media="screen">@import "firebug.css";</style>
+<style>html,body{margin:0;padding:0;overflow:hidden;}</style>
+</head>
+<body class="fbBody">
+<table id="fbChrome" cellpadding="0" cellspacing="0" border="0">
+  <tbody>
+    <tr>
+      <!-- Interface - Top Area -->
+      <td id="fbTop" colspan="2">
+      
+        <!-- 
+        <div>
+          --><!-- <span id="fbToolbarErrors" class="fbErrors">2 errors</span> --><!-- 
+          <input type="text" id="fbToolbarSearch" />
+        </div>
+        -->
+              
+        <!-- Window Buttons -->
+        <div id="fbWindowButtons">
+          <a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page">&nbsp;</a>
+          <a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window">&nbsp;</a>
+          <a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug">&nbsp;</a>
+        </div>
+        
+        <!-- Toolbar buttons and Status Bar -->
+        <div id="fbToolbar">
+          <div id="fbToolbarContent">
+        
+          <!-- Firebug Button -->
+          <span id="fbToolbarIcon">
+            <a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank">&nbsp;</a>
+          </span>
+          
+          <!-- 
+          <span id="fbLeftToolbarErrors" class="fbErrors">2 errors</span>
+           -->
+           
+          <!-- Toolbar Buttons -->
+          <span id="fbToolbarButtons">
+            <!-- Fixed Toolbar Buttons -->
+            <span id="fbFixedButtons">
+                <a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a>
+            </span>
+            
+            <!-- Console Panel Toolbar Buttons -->
+            <span id="fbConsoleButtons" class="fbToolbarButtons">
+              <a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a>
+            </span>
+            
+            <!-- HTML Panel Toolbar Buttons -->
+            <!-- 
+            <span id="fbHTMLButtons" class="fbToolbarButtons">
+              <a id="fbHTML_btEdit" class="fbHover" title="Edit this HTML">Edit</a>
+            </span>
+             -->
+          </span>
+          
+          <!-- Status Bar -->
+          <span id="fbStatusBarBox">
+            <span class="fbToolbarSeparator"></span>
+            <!-- HTML Panel Status Bar -->
+            <!-- 
+            <span id="fbHTMLStatusBar" class="fbStatusBar fbToolbarButtons">
+            </span>
+             -->
+          </span>
+          
+          </div>
+          
+        </div>
+        
+        <!-- PanelBars -->
+        <div id="fbPanelBarBox">
+        
+          <!-- Main PanelBar -->
+          <div id="fbPanelBar1" class="fbPanelBar">
+            <a id="fbConsoleTab" class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">Console</span>
+                <span class="fbTabMenuTarget"></span>
+                <span class="fbTabR"></span>
+            </a>
+            <a id="fbHTMLTab" class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">HTML</span>
+                <span class="fbTabR"></span>
+            </a>
+            <a class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">CSS</span>
+                <span class="fbTabR"></span>
+            </a>
+            <a class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">Script</span>
+                <span class="fbTabR"></span>
+            </a>
+            <a class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">DOM</span>
+                <span class="fbTabR"></span>
+            </a>
+          </div>
+
+          <!-- Side PanelBars -->
+          <div id="fbPanelBar2Box" class="hide">
+            <div id="fbPanelBar2" class="fbPanelBar">
+            <!-- 
+              <a class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">Style</span>
+                <span class="fbTabR"></span>
+              </a>
+              <a class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">Layout</span>
+                <span class="fbTabR"></span>
+              </a>
+              <a class="fbTab fbHover">
+                <span class="fbTabL"></span>
+                <span class="fbTabText">DOM</span>
+                <span class="fbTabR"></span>
+              </a>
+           -->
+            </div>
+          </div>
+          
+        </div>
+        
+        <!-- Horizontal Splitter -->
+        <div id="fbHSplitter">&nbsp;</div>
+        
+      </td>
+    </tr>
+    
+    <!-- Interface - Main Area -->
+    <tr id="fbContent">
+    
+      <!-- Panels  -->
+      <td id="fbPanelBox1">
+        <div id="fbPanel1" class="fbFitHeight">
+          <div id="fbConsole" class="fbPanel"></div>
+          <div id="fbHTML" class="fbPanel"></div>
+        </div>
+      </td>
+      
+      <!-- Side Panel Box -->
+      <td id="fbPanelBox2" class="hide">
+      
+        <!-- VerticalSplitter -->
+        <div id="fbVSplitter" class="fbVSplitter">&nbsp;</div>
+        
+        <!-- Side Panels -->
+        <div id="fbPanel2" class="fbFitHeight">
+        
+          <!-- HTML Side Panels -->
+          <div id="fbHTML_Style" class="fbPanel"></div>
+          <div id="fbHTML_Layout" class="fbPanel"></div>
+          <div id="fbHTML_DOM" class="fbPanel"></div>
+          
+        </div>
+        
+        <!-- Large Command Line -->
+        <textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea>
+        
+        <!-- Large Command Line Buttons -->
+        <div id="fbLargeCommandButtons">
+            <a id="fbCommand_btRun" class="fbButton fbHover">Run</a>
+            <a id="fbCommand_btClear" class="fbButton fbHover">Clear</a>
+            
+            <a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a>
+        </div>
+        
+      </td>
+      
+    </tr>
+    
+    <!-- Interface - Bottom Area -->
+    <tr id="fbBottom" class="hide">
+    
+      <!-- Command Line -->
+      <td id="fbCommand" colspan="2">
+        <div id="fbCommandBox">
+          <div id="fbCommandIcon">&gt;&gt;&gt;</div>
+          <input id="fbCommandLine" name="fbCommandLine" type="text" />
+          <a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a>
+        </div>
+      </td>
+      
+    </tr>
+    
+  </tbody>
+</table> 
+<span id="fbMiniChrome">
+  <span id="fbMiniContent">
+    <span id="fbMiniIcon" title="Open Firebug Lite"></span>
+    <span id="fbMiniErrors" class="fbErrors"><!-- 2 errors --></span>
+  </span>
+</span>
+<!-- 
+<div id="fbErrorPopup">
+  <div id="fbErrorPopupContent">
+    <div id="fbErrorIndicator" class="fbErrors">2 errors</div>
+  </div>
+</div>
+ -->
+</body>
+</html>
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.png
new file mode 100644
index 0000000..e10affe
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/firebug.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/group.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/group.gif
new file mode 100644
index 0000000..8db97c2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/group.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/html.css b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/html.css
new file mode 100644
index 0000000..5b7c5f4
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/html.css
@@ -0,0 +1,272 @@
+/* See license.txt for terms of usage */
+
+.panelNode-html {
+    -moz-box-sizing: padding-box;
+    padding: 4px 0 0 2px;
+}
+
+.nodeBox {
+    position: relative;
+    font-family: Monaco, monospace;
+    padding-left: 13px;
+    -moz-user-select: -moz-none;
+}
+.nodeBox.search-selection {
+    -moz-user-select: text;
+}
+.twisty {
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    width: 14px;
+    height: 14px;
+}
+
+.nodeChildBox {
+    margin-left: 12px;
+    display: none;
+}
+
+.nodeLabel,
+.nodeCloseLabel {
+    margin: -2px 2px 0 2px;
+    border: 2px solid transparent;
+    -moz-border-radius: 3px;
+    padding: 0 2px;
+    color: #000088;
+}
+
+.nodeCloseLabel {
+    display: none;
+}
+
+.nodeTag {
+    cursor: pointer;
+    color: blue;
+}
+
+.nodeValue {
+    color: #FF0000;
+    font-weight: normal;
+}
+
+.nodeText,
+.nodeComment {
+    margin: 0 2px;
+    vertical-align: top;
+}
+
+.nodeText {
+    color: #333333;
+}
+
+.nodeWhiteSpace {
+    border: 1px solid LightGray;
+    white-space: pre; /* otherwise the border will be collapsed around zero pixels */
+    margin-left: 1px;
+    color: gray;
+}
+
+
+.nodeWhiteSpace_Space {
+    border: 1px solid #ddd;
+}
+
+.nodeTextEntity {
+    border: 1px solid gray;
+    white-space: pre; /* otherwise the border will be collapsed around zero pixels */
+    margin-left: 1px;
+}
+
+.nodeComment {
+    color: DarkGreen;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeBox.highlightOpen > .nodeLabel {
+    background-color: #EEEEEE;
+}
+
+.nodeBox.highlightOpen > .nodeCloseLabel,
+.nodeBox.highlightOpen > .nodeChildBox,
+.nodeBox.open > .nodeCloseLabel,
+.nodeBox.open > .nodeChildBox {
+    display: block;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeBox.selected > .nodeLabel > .nodeLabelBox,
+.nodeBox.selected > .nodeLabel {
+    border-color: Highlight;
+    background-color: Highlight;
+    color: HighlightText !important;
+}
+
+.nodeBox.selected > .nodeLabel > .nodeLabelBox,
+.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
+.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
+.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
+    color: inherit !important;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeBox.highlighted > .nodeLabel {
+    border-color: Highlight !important;
+    background-color: cyan !important;
+    color: #000000 !important;
+}
+
+.nodeBox.highlighted > .nodeLabel > .nodeLabelBox,
+.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeTag,
+.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
+.nodeBox.highlighted > .nodeLabel > .nodeLabelBox > .nodeText {
+    color: #000000 !important;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox,
+.nodeBox.nodeHidden .nodeCloseLabel,
+.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeText,
+.nodeBox.nodeHidden .nodeText {
+    color: #888888;
+}
+
+.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeTag,
+.nodeBox.nodeHidden .nodeCloseLabel > .nodeCloseLabelBox > .nodeTag {
+    color: #5F82D9;
+}
+
+.nodeBox.nodeHidden .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue {
+    color: #D86060;
+}
+
+.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
+.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
+.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
+.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
+    color: SkyBlue !important;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+.nodeBox.mutated > .nodeLabel,
+.nodeAttr.mutated,
+.nodeValue.mutated,
+.nodeText.mutated,
+.nodeBox.mutated > .nodeText {
+    background-color: #EFFF79;
+    color: #FF0000 !important;
+}
+
+.nodeBox.selected.mutated > .nodeLabel,
+.nodeBox.selected.mutated > .nodeLabel > .nodeLabelBox,
+.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr.mutated > .nodeValue,
+.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue.mutated,
+.nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText.mutated {
+    background-color: #EFFF79;
+    border-color: #EFFF79;
+    color: #FF0000 !important;
+}
+
+/************************************************************************************************/
+
+.logRow-dirxml {
+    padding-left: 0;
+}
+
+.soloElement > .nodeBox  {
+    padding-left: 0;
+}
+
+.useA11y .nodeLabel.focused {
+    outline: 2px solid #FF9933;
+    -moz-outline-radius: 3px;
+    outline-offset: -2px;
+}
+
+.useA11y .nodeLabelBox:focus {
+    outline: none;
+}
+
+/************************************************************************************************/
+
+.breakpointCode .twisty {
+    display: none;
+}
+
+.breakpointCode .nodeBox.containerNodeBox,
+.breakpointCode .nodeLabel {
+    padding-left: 0px;
+    margin-left: 0px;
+    font-family: Monaco, monospace !important;
+}
+
+.breakpointCode .nodeTag,
+.breakpointCode .nodeAttr,
+.breakpointCode .nodeText,
+.breakpointCode .nodeValue,
+.breakpointCode .nodeLabel {
+    color: DarkGreen !important;
+}
+
+.breakpointMutationType {
+    position: absolute;
+    top: 4px;
+    right: 20px;
+    color: gray;
+}
+
+
+
+
+
+
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+/************************************************************************************************/
+
+
+
+/************************************************************************************************/
+/* Twisties */
+
+.twisty,
+.logRow-errorMessage > .hasTwisty > .errorTitle,
+.logRow-log > .objectBox-array.hasTwisty,
+.logRow-spy .spyHead .spyTitle,
+.logGroup > .logRow,
+.memberRow.hasChildren > .memberLabelCell > .memberLabel,
+.hasHeaders .netHrefLabel,
+.netPageRow > .netCol > .netPageTitle {
+    background-image: url(twistyClosed.png);
+    background-repeat: no-repeat;
+    background-position: 2px 2px;
+	min-height: 12px;
+}
+
+.logRow-errorMessage > .hasTwisty.opened > .errorTitle,
+.logRow-log > .objectBox-array.hasTwisty.opened,
+.logRow-spy.opened .spyHead .spyTitle,
+.logGroup.opened > .logRow,
+.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,
+.nodeBox.highlightOpen > .nodeLabel > .twisty,
+.nodeBox.open > .nodeLabel > .twisty,
+.netRow.opened > .netCol > .netHrefLabel,
+.netPageRow.opened > .netCol > .netPageTitle {
+    background-image: url(twistyOpen.png);
+}
+
+.twisty {
+    background-position: 4px 4px;
+}
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/infoIcon.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/infoIcon.gif
new file mode 100644
index 0000000..0618e20
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/infoIcon.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/infoIcon.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/infoIcon.png
new file mode 100644
index 0000000..da1e533
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/infoIcon.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/loading_16.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/loading_16.gif
new file mode 100644
index 0000000..085ccae
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/loading_16.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/min.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/min.png
new file mode 100644
index 0000000..1034d66
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/min.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/minHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/minHover.png
new file mode 100644
index 0000000..b0d1e1a
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/minHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/off.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/off.png
new file mode 100644
index 0000000..b70b1d2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/off.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/offHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/offHover.png
new file mode 100644
index 0000000..f3670f1
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/offHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gif
new file mode 100644
index 0000000..6865c96
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/pixel_transparent.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg
new file mode 100644
index 0000000..2dfa728
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/roundCorner.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg">
+  <rect fill="white"  x="0" y="0" width="100%" height="100%" />
+  <rect fill="highlight"  x="0" y="0" width="100%" height="100%" rx="2px"/>
+</svg>
+
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/search.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/search.gif
new file mode 100644
index 0000000..2a62098
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/search.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/search.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/search.png
new file mode 100644
index 0000000..fba33b8
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/search.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadow.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadow.gif
new file mode 100644
index 0000000..af7f537
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadow.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadow2.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadow2.gif
new file mode 100644
index 0000000..099cbf3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadow2.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.png
new file mode 100644
index 0000000..a2561df
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/shadowAlpha.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/sprite.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/sprite.png
new file mode 100644
index 0000000..33d2c4d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/sprite.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.png
new file mode 100644
index 0000000..0fb24d0
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverLeft.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.png
new file mode 100644
index 0000000..fbccab5
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverMid.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.png
new file mode 100644
index 0000000..3db0f36
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabHoverRight.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabLeft.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabLeft.png
new file mode 100644
index 0000000..a6cc9e9
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabLeft.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.png
new file mode 100644
index 0000000..4726e62
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuCheckbox.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.png
new file mode 100644
index 0000000..eb4b11e
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuPin.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.png
new file mode 100644
index 0000000..55b982d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuRadio.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.png
new file mode 100644
index 0000000..957bd9f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuTarget.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.png
new file mode 100644
index 0000000..200a370
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMenuTargetHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMid.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMid.png
new file mode 100644
index 0000000..68986c3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabMid.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabRight.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabRight.png
new file mode 100644
index 0000000..5011307
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tabRight.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gif
new file mode 100644
index 0000000..0ee5497
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.png
new file mode 100644
index 0000000..21682c3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorBorders.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gif
new file mode 100644
index 0000000..04f8421
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.png
new file mode 100644
index 0000000..a0f839d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/textEditorCorners.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/titlebarMid.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/titlebarMid.png
new file mode 100644
index 0000000..10998ae
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/titlebarMid.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/toolbarMid.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/toolbarMid.png
new file mode 100644
index 0000000..aa21dee
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/toolbarMid.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tree_close.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tree_close.gif
new file mode 100644
index 0000000..e26728a
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tree_close.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tree_open.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tree_open.gif
new file mode 100644
index 0000000..edf662f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/tree_open.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/twistyClosed.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/twistyClosed.png
new file mode 100644
index 0000000..f80319b
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/twistyClosed.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/twistyOpen.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/twistyOpen.png
new file mode 100644
index 0000000..8680124
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/twistyOpen.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/up.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/up.png
new file mode 100644
index 0000000..2174d03
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/up.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/upActive.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/upActive.png
new file mode 100644
index 0000000..236cf67
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/upActive.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/upHover.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/upHover.png
new file mode 100644
index 0000000..cd81317
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/upHover.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/warningIcon.gif b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/warningIcon.gif
new file mode 100644
index 0000000..8497278
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/warningIcon.gif
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/warningIcon.png b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/warningIcon.png
new file mode 100644
index 0000000..de51084
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/skin/xp/warningIcon.png
Binary files differ
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/src/firebug-lite-debug.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/src/firebug-lite-debug.js
new file mode 100644
index 0000000..40b1ae7
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/firebug-lite/src/firebug-lite-debug.js
@@ -0,0 +1,31176 @@
+(function(){
+
+/*!*************************************************************
+ *
+ *    Firebug Lite 1.4.0
+ *
+ *      Copyright (c) 2007, Parakey Inc.
+ *      Released under BSD license.
+ *      More information: http://getfirebug.com/firebuglite
+ *
+ **************************************************************/
+
+/*!
+ * CSS selectors powered by:
+ *
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+
+/** @namespace describe lib */
+
+// FIXME: xxxpedro if we use "var FBL = {}" the FBL won't appear in the DOM Panel in IE
+var FBL = {};
+
+( /** @scope s_lib @this FBL */ function() {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Constants
+
+var productionDir = "http://getfirebug.com/releases/lite/";
+var bookmarkletVersion = 4;
+
+// ************************************************************************************************
+
+var reNotWhitespace = /[^\s]/;
+var reSplitFile = /:\/{1,3}(.*?)\/([^\/]*?)\/?($|\?.*)/;
+
+// Globals
+this.reJavascript = /\s*javascript:\s*(.*)/;
+this.reChrome = /chrome:\/\/([^\/]*)\//;
+this.reFile = /file:\/\/([^\/]*)\//;
+
+
+// ************************************************************************************************
+// properties
+
+var userAgent = navigator.userAgent.toLowerCase();
+this.isFirefox = /firefox/.test(userAgent);
+this.isOpera   = /opera/.test(userAgent);
+this.isSafari  = /webkit/.test(userAgent);
+this.isIE      = /msie/.test(userAgent) && !/opera/.test(userAgent);
+this.isIE6     = /msie 6/i.test(navigator.appVersion);
+this.browserVersion = (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1];
+this.isIElt8   = this.isIE && (this.browserVersion-0 < 8);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.NS = null;
+this.pixelsPerInch = null;
+
+
+// ************************************************************************************************
+// Namespaces
+
+var namespaces = [];
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.ns = function(fn)
+{
+    var ns = {};
+    namespaces.push(fn, ns);
+    return ns;
+};
+
+var FBTrace = null;
+
+this.initialize = function()
+{
+    // Firebug Lite is already running in persistent mode so we just quit
+    if (window.firebug && firebug.firebuglite || window.console && console.firebuglite)
+        return;
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // initialize environment
+
+    // point the FBTrace object to the local variable
+    if (FBL.FBTrace)
+        FBTrace = FBL.FBTrace;
+    else
+        FBTrace = FBL.FBTrace = {};
+
+    // check if the actual window is a persisted chrome context
+    var isChromeContext = window.Firebug && typeof window.Firebug.SharedEnv == "object";
+
+    // chrome context of the persistent application
+    if (isChromeContext)
+    {
+        // TODO: xxxpedro persist - make a better synchronization
+        sharedEnv = window.Firebug.SharedEnv;
+        delete window.Firebug.SharedEnv;
+
+        FBL.Env = sharedEnv;
+        FBL.Env.isChromeContext = true;
+        FBTrace.messageQueue = FBL.Env.traceMessageQueue;
+    }
+    // non-persistent application
+    else
+    {
+        FBL.NS = document.documentElement.namespaceURI;
+        FBL.Env.browser = window;
+        FBL.Env.destroy = destroyEnvironment;
+
+        if (document.documentElement.getAttribute("debug") == "true")
+            FBL.Env.Options.startOpened = true;
+
+        // find the URL location of the loaded application
+        findLocation();
+
+        // TODO: get preferences here...
+        // The problem is that we don't have the Firebug object yet, so we can't use
+        // Firebug.loadPrefs. We're using the Store module directly instead.
+        var prefs = FBL.Store.get("FirebugLite") || {};
+        FBL.Env.DefaultOptions = FBL.Env.Options;
+        FBL.Env.Options = FBL.extend(FBL.Env.Options, prefs.options || {});
+
+        if (FBL.isFirefox &&
+            typeof FBL.Env.browser.console == "object" &&
+            FBL.Env.browser.console.firebug &&
+            FBL.Env.Options.disableWhenFirebugActive)
+                return;
+    }
+
+    // exposes the FBL to the global namespace when in debug mode
+    if (FBL.Env.isDebugMode)
+    {
+        FBL.Env.browser.FBL = FBL;
+    }
+
+    // check browser compatibilities
+    this.isQuiksMode = FBL.Env.browser.document.compatMode == "BackCompat";
+    this.isIEQuiksMode = this.isIE && this.isQuiksMode;
+    this.isIEStantandMode = this.isIE && !this.isQuiksMode;
+
+    this.noFixedPosition = this.isIE6 || this.isIEQuiksMode;
+
+    // after creating/synchronizing the environment, initialize the FBTrace module
+    if (FBL.Env.Options.enableTrace) FBTrace.initialize();
+
+    if (FBTrace.DBG_INITIALIZE && isChromeContext) FBTrace.sysout("FBL.initialize - persistent application", "initialize chrome context");
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // initialize namespaces
+
+    if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FBL.initialize", namespaces.length/2+" namespaces BEGIN");
+
+    for (var i = 0; i < namespaces.length; i += 2)
+    {
+        var fn = namespaces[i];
+        var ns = namespaces[i+1];
+        fn.apply(ns);
+    }
+
+    if (FBTrace.DBG_INITIALIZE) {
+        FBTrace.sysout("FBL.initialize", namespaces.length/2+" namespaces END");
+        FBTrace.sysout("FBL waitForDocument", "waiting document load");
+    }
+
+    FBL.Ajax.initialize();
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // finish environment initialization
+    FBL.Firebug.loadPrefs();
+
+    if (FBL.Env.Options.enablePersistent)
+    {
+        // TODO: xxxpedro persist - make a better synchronization
+        if (isChromeContext)
+        {
+            FBL.FirebugChrome.clone(FBL.Env.FirebugChrome);
+        }
+        else
+        {
+            FBL.Env.FirebugChrome = FBL.FirebugChrome;
+            FBL.Env.traceMessageQueue = FBTrace.messageQueue;
+        }
+    }
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // wait document load
+
+    waitForDocument();
+};
+
+var waitForDocument = function waitForDocument()
+{
+    // document.body not available in XML+XSL documents in Firefox
+    var doc = FBL.Env.browser.document;
+    var body = doc.getElementsByTagName("body")[0];
+
+    if (body)
+    {
+        calculatePixelsPerInch(doc, body);
+        onDocumentLoad();
+    }
+    else
+        setTimeout(waitForDocument, 50);
+};
+
+var onDocumentLoad = function onDocumentLoad()
+{
+    if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FBL onDocumentLoad", "document loaded");
+
+    // fix IE6 problem with cache of background images, causing a lot of flickering
+    if (FBL.isIE6)
+        fixIE6BackgroundImageCache();
+
+    // chrome context of the persistent application
+    if (FBL.Env.Options.enablePersistent && FBL.Env.isChromeContext)
+    {
+        // finally, start the application in the chrome context
+        FBL.Firebug.initialize();
+
+        // if is not development mode, remove the shared environment cache object
+        // used to synchronize the both persistent contexts
+        if (!FBL.Env.isDevelopmentMode)
+        {
+            sharedEnv.destroy();
+            sharedEnv = null;
+        }
+    }
+    // non-persistent application
+    else
+    {
+        FBL.FirebugChrome.create();
+    }
+};
+
+// ************************************************************************************************
+// Env
+
+var sharedEnv;
+
+this.Env =
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Env Options (will be transported to Firebug options)
+    Options:
+    {
+        saveCookies: true,
+
+        saveWindowPosition: false,
+        saveCommandLineHistory: false,
+
+        startOpened: false,
+        startInNewWindow: false,
+        showIconWhenHidden: true,
+
+        overrideConsole: true,
+        ignoreFirebugElements: true,
+        disableWhenFirebugActive: true,
+
+        disableXHRListener: false,
+        disableResourceFetching: false,
+
+        enableTrace: false,
+        enablePersistent: false
+
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Library location
+    Location:
+    {
+        sourceDir: null,
+        baseDir: null,
+        skinDir: null,
+        skin: null,
+        app: null
+    },
+
+    skin: "xp",
+    useLocalSkin: false,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Env states
+    isDevelopmentMode: false,
+    isDebugMode: false,
+    isChromeContext: false,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Env references
+    browser: null,
+    chrome: null
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var destroyEnvironment = function destroyEnvironment()
+{
+    setTimeout(function()
+    {
+        FBL = null;
+    }, 100);
+};
+
+// ************************************************************************************************
+// Library location
+
+var findLocation =  function findLocation()
+{
+    var reFirebugFile = /(firebug-lite(?:-\w+)?(?:\.js|\.jgz))(?:#(.+))?$/;
+    var reGetFirebugSite = /(?:http|https):\/\/getfirebug.com\//;
+    var isGetFirebugSite;
+
+    var rePath = /^(.*\/)/;
+    var reProtocol = /^\w+:\/\//;
+    var path = null;
+    var doc = document;
+
+    // Firebug Lite 1.3.0 bookmarklet identification
+    var script = doc.getElementById("FirebugLite");
+
+    var scriptSrc;
+    var hasSrcAttribute = true;
+
+    // If the script was loaded via bookmarklet, we already have the script tag
+    if (script)
+    {
+        scriptSrc = script.src;
+        file = reFirebugFile.exec(scriptSrc);
+
+        var version = script.getAttribute("FirebugLite");
+        var number = version ? parseInt(version) : 0;
+
+        if (!version || !number || number < bookmarkletVersion)
+        {
+            FBL.Env.bookmarkletOutdated = true;
+        }
+    }
+    // otherwise we must search for the correct script tag
+    else
+    {
+        for(var i=0, s=doc.getElementsByTagName("script"), si; si=s[i]; i++)
+        {
+            var file = null;
+            if ( si.nodeName.toLowerCase() == "script" )
+            {
+                if (file = reFirebugFile.exec(si.getAttribute("firebugSrc")))
+                {
+                    scriptSrc = si.getAttribute("firebugSrc");
+                    hasSrcAttribute = false;
+                }
+                else if (file = reFirebugFile.exec(si.src))
+                {
+                    scriptSrc = si.src;
+                }
+                else
+                    continue;
+
+                script = si;
+                break;
+            }
+        }
+    }
+
+    // mark the script tag to be ignored by Firebug Lite
+    if (script)
+        script.firebugIgnore = true;
+
+    if (file)
+    {
+        var fileName = file[1];
+        var fileOptions = file[2];
+
+        // absolute path
+        if (reProtocol.test(scriptSrc)) {
+            path = rePath.exec(scriptSrc)[1];
+
+        }
+        // relative path
+        else
+        {
+            var r = rePath.exec(scriptSrc);
+            var src = r ? r[1] : scriptSrc;
+            var backDir = /^((?:\.\.\/)+)(.*)/.exec(src);
+            var reLastDir = /^(.*\/)[^\/]+\/$/;
+            path = rePath.exec(location.href)[1];
+
+            // "../some/path"
+            if (backDir)
+            {
+                var j = backDir[1].length/3;
+                var p;
+                while (j-- > 0)
+                    path = reLastDir.exec(path)[1];
+
+                path += backDir[2];
+            }
+
+            else if(src.indexOf("/") != -1)
+            {
+                // "./some/path"
+                if(/^\.\/./.test(src))
+                {
+                    path += src.substring(2);
+                }
+                // "/some/path"
+                else if(/^\/./.test(src))
+                {
+                    var domain = /^(\w+:\/\/[^\/]+)/.exec(path);
+                    path = domain[1] + src;
+                }
+                // "some/path"
+                else
+                {
+                    path += src;
+                }
+            }
+        }
+    }
+
+    FBL.Env.isChromeExtension = script && script.getAttribute("extension") == "Chrome";
+    if (FBL.Env.isChromeExtension)
+    {
+        path = productionDir;
+        FBL.Env.bookmarkletOutdated = false;
+        script = {innerHTML: "{showIconWhenHidden:false}"};
+    }
+
+    isGetFirebugSite = reGetFirebugSite.test(path);
+
+    if (isGetFirebugSite && path.indexOf("/releases/lite/") == -1)
+    {
+        // See Issue 4587 - If we are loading the script from getfirebug.com shortcut, like
+        // https://getfirebug.com/firebug-lite.js, then we must manually add the full path,
+        // otherwise the Env.Location will hold the wrong path, which will in turn lead to
+        // undesirable effects like the problem in Issue 4587
+        path += "releases/lite/" + (fileName == "firebug-lite-beta.js" ? "beta/" : "latest/");
+    }
+
+    var m = path && path.match(/([^\/]+)\/$/) || null;
+
+    if (path && m)
+    {
+        var Env = FBL.Env;
+
+        // Always use the local skin when running in the same domain
+        // See Issue 3554: Firebug Lite should use local images when loaded locally
+        Env.useLocalSkin = path.indexOf(location.protocol + "//" + location.host + "/") == 0 &&
+                // but we cannot use the locan skin when loaded from getfirebug.com, otherwise
+                // the bookmarklet won't work when visiting getfirebug.com
+                !isGetFirebugSite;
+
+        // detecting development and debug modes via file name
+        if (fileName == "firebug-lite-dev.js")
+        {
+            Env.isDevelopmentMode = true;
+            Env.isDebugMode = true;
+        }
+        else if (fileName == "firebug-lite-debug.js")
+        {
+            Env.isDebugMode = true;
+        }
+
+        // process the <html debug="true">
+        if (Env.browser.document.documentElement.getAttribute("debug") == "true")
+        {
+            Env.Options.startOpened = true;
+        }
+
+        // process the Script URL Options
+        if (fileOptions)
+        {
+            var options = fileOptions.split(",");
+
+            for (var i = 0, length = options.length; i < length; i++)
+            {
+                var option = options[i];
+                var name, value;
+
+                if (option.indexOf("=") != -1)
+                {
+                    var parts = option.split("=");
+                    name = parts[0];
+                    value = eval(unescape(parts[1]));
+                }
+                else
+                {
+                    name = option;
+                    value = true;
+                }
+
+                if (name == "debug")
+                {
+                    Env.isDebugMode = !!value;
+                }
+                else if (name in Env.Options)
+                {
+                    Env.Options[name] = value;
+                }
+                else
+                {
+                    Env[name] = value;
+                }
+            }
+        }
+
+        // process the Script JSON Options
+        if (hasSrcAttribute)
+        {
+            var innerOptions = FBL.trim(script.innerHTML);
+            if (innerOptions)
+            {
+                var innerOptionsObject = eval("(" + innerOptions + ")");
+
+                for (var name in innerOptionsObject)
+                {
+                    var value = innerOptionsObject[name];
+
+                    if (name == "debug")
+                    {
+                        Env.isDebugMode = !!value;
+                    }
+                    else if (name in Env.Options)
+                    {
+                        Env.Options[name] = value;
+                    }
+                    else
+                    {
+                        Env[name] = value;
+                    }
+                }
+            }
+        }
+
+        if (!Env.Options.saveCookies)
+            FBL.Store.remove("FirebugLite");
+
+        // process the Debug Mode
+        if (Env.isDebugMode)
+        {
+            Env.Options.startOpened = true;
+            Env.Options.enableTrace = true;
+            Env.Options.disableWhenFirebugActive = false;
+        }
+
+        var loc = Env.Location;
+        var isProductionRelease = path.indexOf(productionDir) != -1;
+
+        loc.sourceDir = path;
+        loc.baseDir = path.substr(0, path.length - m[1].length - 1);
+        loc.skinDir = (isProductionRelease ? path : loc.baseDir) + "skin/" + Env.skin + "/";
+        loc.skin = loc.skinDir + "firebug.html";
+        loc.app = path + fileName;
+    }
+    else
+    {
+        throw new Error("Firebug Error: Library path not found");
+    }
+};
+
+// ************************************************************************************************
+// Basics
+
+this.bind = function()  // fn, thisObject, args => thisObject.fn(args, arguments);
+{
+   var args = cloneArray(arguments), fn = args.shift(), object = args.shift();
+   return function() { return fn.apply(object, arrayInsert(cloneArray(args), 0, arguments)); };
+};
+
+this.bindFixed = function() // fn, thisObject, args => thisObject.fn(args);
+{
+    var args = cloneArray(arguments), fn = args.shift(), object = args.shift();
+    return function() { return fn.apply(object, args); };
+};
+
+this.extend = function(l, r)
+{
+    var newOb = {};
+    for (var n in l)
+        newOb[n] = l[n];
+    for (var n in r)
+        newOb[n] = r[n];
+    return newOb;
+};
+
+this.descend = function(prototypeParent, childProperties)
+{
+    function protoSetter() {};
+    protoSetter.prototype = prototypeParent;
+    var newOb = new protoSetter();
+    for (var n in childProperties)
+        newOb[n] = childProperties[n];
+    return newOb;
+};
+
+this.append = function(l, r)
+{
+    for (var n in r)
+        l[n] = r[n];
+
+    return l;
+};
+
+this.keys = function(map)  // At least sometimes the keys will be on user-level window objects
+{
+    var keys = [];
+    try
+    {
+        for (var name in map)  // enumeration is safe
+            keys.push(name);   // name is string, safe
+    }
+    catch (exc)
+    {
+        // Sometimes we get exceptions trying to iterate properties
+    }
+
+    return keys;  // return is safe
+};
+
+this.values = function(map)
+{
+    var values = [];
+    try
+    {
+        for (var name in map)
+        {
+            try
+            {
+                values.push(map[name]);
+            }
+            catch (exc)
+            {
+                // Sometimes we get exceptions trying to access properties
+                if (FBTrace.DBG_ERRORS)
+                    FBTrace.sysout("lib.values FAILED ", exc);
+            }
+
+        }
+    }
+    catch (exc)
+    {
+        // Sometimes we get exceptions trying to iterate properties
+        if (FBTrace.DBG_ERRORS)
+            FBTrace.sysout("lib.values FAILED ", exc);
+    }
+
+    return values;
+};
+
+this.remove = function(list, item)
+{
+    for (var i = 0; i < list.length; ++i)
+    {
+        if (list[i] == item)
+        {
+            list.splice(i, 1);
+            break;
+        }
+    }
+};
+
+this.sliceArray = function(array, index)
+{
+    var slice = [];
+    for (var i = index; i < array.length; ++i)
+        slice.push(array[i]);
+
+    return slice;
+};
+
+function cloneArray(array, fn)
+{
+   var newArray = [];
+
+   if (fn)
+       for (var i = 0; i < array.length; ++i)
+           newArray.push(fn(array[i]));
+   else
+       for (var i = 0; i < array.length; ++i)
+           newArray.push(array[i]);
+
+   return newArray;
+}
+
+function extendArray(array, array2)
+{
+   var newArray = [];
+   newArray.push.apply(newArray, array);
+   newArray.push.apply(newArray, array2);
+   return newArray;
+}
+
+this.extendArray = extendArray;
+this.cloneArray = cloneArray;
+
+function arrayInsert(array, index, other)
+{
+   for (var i = 0; i < other.length; ++i)
+       array.splice(i+index, 0, other[i]);
+
+   return array;
+}
+
+// ************************************************************************************************
+
+this.createStyleSheet = function(doc, url)
+{
+    //TODO: xxxpedro
+    //var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
+    var style = this.createElement("link");
+    style.setAttribute("charset","utf-8");
+    style.firebugIgnore = true;
+    style.setAttribute("rel", "stylesheet");
+    style.setAttribute("type", "text/css");
+    style.setAttribute("href", url);
+
+    //TODO: xxxpedro
+    //style.innerHTML = this.getResource(url);
+    return style;
+};
+
+this.addStyleSheet = function(doc, style)
+{
+    var heads = doc.getElementsByTagName("head");
+    if (heads.length)
+        heads[0].appendChild(style);
+    else
+        doc.documentElement.appendChild(style);
+};
+
+this.appendStylesheet = function(doc, uri)
+{
+    // Make sure the stylesheet is not appended twice.
+    if (this.$(uri, doc))
+        return;
+
+    var styleSheet = this.createStyleSheet(doc, uri);
+    styleSheet.setAttribute("id", uri);
+    this.addStyleSheet(doc, styleSheet);
+};
+
+this.addScript = function(doc, id, src)
+{
+    var element = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script");
+    element.setAttribute("type", "text/javascript");
+    element.setAttribute("id", id);
+    if (!FBTrace.DBG_CONSOLE)
+        FBL.unwrapObject(element).firebugIgnore = true;
+
+    element.innerHTML = src;
+    if (doc.documentElement)
+        doc.documentElement.appendChild(element);
+    else
+    {
+        // See issue 1079, the svg test case gives this error
+        if (FBTrace.DBG_ERRORS)
+            FBTrace.sysout("lib.addScript doc has no documentElement:", doc);
+    }
+    return element;
+};
+
+
+// ************************************************************************************************
+
+this.getStyle = this.isIE ?
+    function(el, name)
+    {
+        return el.currentStyle[name] || el.style[name] || undefined;
+    }
+    :
+    function(el, name)
+    {
+        return el.ownerDocument.defaultView.getComputedStyle(el,null)[name]
+            || el.style[name] || undefined;
+    };
+
+
+// ************************************************************************************************
+// Whitespace and Entity conversions
+
+var entityConversionLists = this.entityConversionLists = {
+    normal : {
+        whitespace : {
+            '\t' : '\u200c\u2192',
+            '\n' : '\u200c\u00b6',
+            '\r' : '\u200c\u00ac',
+            ' '  : '\u200c\u00b7'
+        }
+    },
+    reverse : {
+        whitespace : {
+            '&Tab;' : '\t',
+            '&NewLine;' : '\n',
+            '\u200c\u2192' : '\t',
+            '\u200c\u00b6' : '\n',
+            '\u200c\u00ac' : '\r',
+            '\u200c\u00b7' : ' '
+        }
+    }
+};
+
+var normal = entityConversionLists.normal,
+    reverse = entityConversionLists.reverse;
+
+function addEntityMapToList(ccode, entity)
+{
+    var lists = Array.prototype.slice.call(arguments, 2),
+        len = lists.length,
+        ch = String.fromCharCode(ccode);
+    for (var i = 0; i < len; i++)
+    {
+        var list = lists[i];
+        normal[list]=normal[list] || {};
+        normal[list][ch] = '&' + entity + ';';
+        reverse[list]=reverse[list] || {};
+        reverse[list]['&' + entity + ';'] = ch;
+    }
+};
+
+var e = addEntityMapToList,
+    white = 'whitespace',
+    text = 'text',
+    attr = 'attributes',
+    css = 'css',
+    editor = 'editor';
+
+e(0x0022, 'quot', attr, css);
+e(0x0026, 'amp', attr, text, css);
+e(0x0027, 'apos', css);
+e(0x003c, 'lt', attr, text, css);
+e(0x003e, 'gt', attr, text, css);
+e(0xa9, 'copy', text, editor);
+e(0xae, 'reg', text, editor);
+e(0x2122, 'trade', text, editor);
+
+// See http://en.wikipedia.org/wiki/Dash
+e(0x2012, '#8210', attr, text, editor); // figure dash
+e(0x2013, 'ndash', attr, text, editor); // en dash
+e(0x2014, 'mdash', attr, text, editor); // em dash
+e(0x2015, '#8213', attr, text, editor); // horizontal bar
+
+e(0x00a0, 'nbsp', attr, text, white, editor);
+e(0x2002, 'ensp', attr, text, white, editor);
+e(0x2003, 'emsp', attr, text, white, editor);
+e(0x2009, 'thinsp', attr, text, white, editor);
+e(0x200c, 'zwnj', attr, text, white, editor);
+e(0x200d, 'zwj', attr, text, white, editor);
+e(0x200e, 'lrm', attr, text, white, editor);
+e(0x200f, 'rlm', attr, text, white, editor);
+e(0x200b, '#8203', attr, text, white, editor); // zero-width space (ZWSP)
+
+//************************************************************************************************
+// Entity escaping
+
+var entityConversionRegexes = {
+        normal : {},
+        reverse : {}
+    };
+
+var escapeEntitiesRegEx = {
+    normal : function(list)
+    {
+        var chars = [];
+        for ( var ch in list)
+        {
+            chars.push(ch);
+        }
+        return new RegExp('([' + chars.join('') + '])', 'gm');
+    },
+    reverse : function(list)
+    {
+        var chars = [];
+        for ( var ch in list)
+        {
+            chars.push(ch);
+        }
+        return new RegExp('(' + chars.join('|') + ')', 'gm');
+    }
+};
+
+function getEscapeRegexp(direction, lists)
+{
+    var name = '', re;
+    var groups = [].concat(lists);
+    for (i = 0; i < groups.length; i++)
+    {
+        name += groups[i].group;
+    }
+    re = entityConversionRegexes[direction][name];
+    if (!re)
+    {
+        var list = {};
+        if (groups.length > 1)
+        {
+            for ( var i = 0; i < groups.length; i++)
+            {
+                var aList = entityConversionLists[direction][groups[i].group];
+                for ( var item in aList)
+                    list[item] = aList[item];
+            }
+        } else if (groups.length==1)
+        {
+            list = entityConversionLists[direction][groups[0].group]; // faster for special case
+        } else {
+            list = {}; // perhaps should print out an error here?
+        }
+        re = entityConversionRegexes[direction][name] = escapeEntitiesRegEx[direction](list);
+    }
+    return re;
+};
+
+function createSimpleEscape(name, direction)
+{
+    return function(value)
+    {
+        var list = entityConversionLists[direction][name];
+        return String(value).replace(
+                getEscapeRegexp(direction, {
+                    group : name,
+                    list : list
+                }),
+                function(ch)
+                {
+                    return list[ch];
+                }
+               );
+    };
+};
+
+function escapeGroupsForEntities(str, lists)
+{
+    lists = [].concat(lists);
+    var re = getEscapeRegexp('normal', lists),
+        split = String(str).split(re),
+        len = split.length,
+        results = [],
+        cur, r, i, ri = 0, l, list, last = '';
+    if (!len)
+        return [ {
+            str : String(str),
+            group : '',
+            name : ''
+        } ];
+    for (i = 0; i < len; i++)
+    {
+        cur = split[i];
+        if (cur == '')
+            continue;
+        for (l = 0; l < lists.length; l++)
+        {
+            list = lists[l];
+            r = entityConversionLists.normal[list.group][cur];
+            // if (cur == ' ' && list.group == 'whitespace' && last == ' ') // only show for runs of more than one space
+            //     r = ' ';
+            if (r)
+            {
+                results[ri] = {
+                    'str' : r,
+                    'class' : list['class'],
+                    'extra' : list.extra[cur] ? list['class']
+                            + list.extra[cur] : ''
+                };
+                break;
+            }
+        }
+        // last=cur;
+        if (!r)
+            results[ri] = {
+                'str' : cur,
+                'class' : '',
+                'extra' : ''
+            };
+        ri++;
+    }
+    return results;
+};
+
+this.escapeGroupsForEntities = escapeGroupsForEntities;
+
+
+function unescapeEntities(str, lists)
+{
+    var re = getEscapeRegexp('reverse', lists),
+        split = String(str).split(re),
+        len = split.length,
+        results = [],
+        cur, r, i, ri = 0, l, list;
+    if (!len)
+        return str;
+    lists = [].concat(lists);
+    for (i = 0; i < len; i++)
+    {
+        cur = split[i];
+        if (cur == '')
+            continue;
+        for (l = 0; l < lists.length; l++)
+        {
+            list = lists[l];
+            r = entityConversionLists.reverse[list.group][cur];
+            if (r)
+            {
+                results[ri] = r;
+                break;
+            }
+        }
+        if (!r)
+            results[ri] = cur;
+        ri++;
+    }
+    return results.join('') || '';
+};
+
+
+// ************************************************************************************************
+// String escaping
+
+var escapeForTextNode = this.escapeForTextNode = createSimpleEscape('text', 'normal');
+var escapeForHtmlEditor = this.escapeForHtmlEditor = createSimpleEscape('editor', 'normal');
+var escapeForElementAttribute = this.escapeForElementAttribute = createSimpleEscape('attributes', 'normal');
+var escapeForCss = this.escapeForCss = createSimpleEscape('css', 'normal');
+
+// deprecated compatibility functions
+//this.deprecateEscapeHTML = createSimpleEscape('text', 'normal');
+//this.deprecatedUnescapeHTML = createSimpleEscape('text', 'reverse');
+//this.escapeHTML = deprecated("use appropriate escapeFor... function", this.deprecateEscapeHTML);
+//this.unescapeHTML = deprecated("use appropriate unescapeFor... function", this.deprecatedUnescapeHTML);
+
+var escapeForSourceLine = this.escapeForSourceLine = createSimpleEscape('text', 'normal');
+
+var unescapeWhitespace = createSimpleEscape('whitespace', 'reverse');
+
+this.unescapeForTextNode = function(str)
+{
+    if (Firebug.showTextNodesWithWhitespace)
+        str = unescapeWhitespace(str);
+    if (!Firebug.showTextNodesWithEntities)
+        str = escapeForElementAttribute(str);
+    return str;
+};
+
+this.escapeNewLines = function(value)
+{
+    return value.replace(/\r/g, "\\r").replace(/\n/g, "\\n");
+};
+
+this.stripNewLines = function(value)
+{
+    return typeof(value) == "string" ? value.replace(/[\r\n]/g, " ") : value;
+};
+
+this.escapeJS = function(value)
+{
+    return value.replace(/\r/g, "\\r").replace(/\n/g, "\\n").replace('"', '\\"', "g");
+};
+
+function escapeHTMLAttribute(value)
+{
+    function replaceChars(ch)
+    {
+        switch (ch)
+        {
+            case "&":
+                return "&amp;";
+            case "'":
+                return apos;
+            case '"':
+                return quot;
+        }
+        return "?";
+    };
+    var apos = "&#39;", quot = "&quot;", around = '"';
+    if( value.indexOf('"') == -1 ) {
+        quot = '"';
+        apos = "'";
+    } else if( value.indexOf("'") == -1 ) {
+        quot = '"';
+        around = "'";
+    }
+    return around + (String(value).replace(/[&'"]/g, replaceChars)) + around;
+}
+
+
+function escapeHTML(value)
+{
+    function replaceChars(ch)
+    {
+        switch (ch)
+        {
+            case "<":
+                return "&lt;";
+            case ">":
+                return "&gt;";
+            case "&":
+                return "&amp;";
+            case "'":
+                return "&#39;";
+            case '"':
+                return "&quot;";
+        }
+        return "?";
+    };
+    return String(value).replace(/[<>&"']/g, replaceChars);
+}
+
+this.escapeHTML = escapeHTML;
+
+this.cropString = function(text, limit)
+{
+    text = text + "";
+
+    if (!limit)
+        var halfLimit = 50;
+    else
+        var halfLimit = limit / 2;
+
+    if (text.length > limit)
+        return this.escapeNewLines(text.substr(0, halfLimit) + "..." + text.substr(text.length-halfLimit));
+    else
+        return this.escapeNewLines(text);
+};
+
+this.isWhitespace = function(text)
+{
+    return !reNotWhitespace.exec(text);
+};
+
+this.splitLines = function(text)
+{
+    var reSplitLines2 = /.*(:?\r\n|\n|\r)?/mg;
+    var lines;
+    if (text.match)
+    {
+        lines = text.match(reSplitLines2);
+    }
+    else
+    {
+        var str = text+"";
+        lines = str.match(reSplitLines2);
+    }
+    lines.pop();
+    return lines;
+};
+
+
+// ************************************************************************************************
+
+this.safeToString = function(ob)
+{
+    if (this.isIE)
+    {
+        try
+        {
+            // FIXME: xxxpedro this is failing in IE for the global "external" object
+            return ob + "";
+        }
+        catch(E)
+        {
+            FBTrace.sysout("Lib.safeToString() failed for ", ob);
+            return "";
+        }
+    }
+
+    try
+    {
+        if (ob && "toString" in ob && typeof ob.toString == "function")
+            return ob.toString();
+    }
+    catch (exc)
+    {
+        // xxxpedro it is not safe to use ob+""?
+        return ob + "";
+        ///return "[an object with no toString() function]";
+    }
+};
+
+// ************************************************************************************************
+
+this.hasProperties = function(ob)
+{
+    try
+    {
+        for (var name in ob)
+            return true;
+    } catch (exc) {}
+    return false;
+};
+
+// ************************************************************************************************
+// String Util
+
+var reTrim = /^\s+|\s+$/g;
+this.trim = function(s)
+{
+    return s.replace(reTrim, "");
+};
+
+
+// ************************************************************************************************
+// Empty
+
+this.emptyFn = function(){};
+
+
+
+// ************************************************************************************************
+// Visibility
+
+this.isVisible = function(elt)
+{
+    /*
+    if (elt instanceof XULElement)
+    {
+        //FBTrace.sysout("isVisible elt.offsetWidth: "+elt.offsetWidth+" offsetHeight:"+ elt.offsetHeight+" localName:"+ elt.localName+" nameSpace:"+elt.nameSpaceURI+"\n");
+        return (!elt.hidden && !elt.collapsed);
+    }
+    /**/
+
+    return this.getStyle(elt, "visibility") != "hidden" &&
+        ( elt.offsetWidth > 0 || elt.offsetHeight > 0
+        || elt.tagName in invisibleTags
+        || elt.namespaceURI == "http://www.w3.org/2000/svg"
+        || elt.namespaceURI == "http://www.w3.org/1998/Math/MathML" );
+};
+
+this.collapse = function(elt, collapsed)
+{
+    // IE6 doesn't support the [collapsed] CSS selector. IE7 does support the selector,
+    // but it is causing a bug (the element disappears when you set the "collapsed"
+    // attribute, but it doesn't appear when you remove the attribute. So, for those
+    // cases, we need to use the class attribute.
+    if (this.isIElt8)
+    {
+        if (collapsed)
+            this.setClass(elt, "collapsed");
+        else
+            this.removeClass(elt, "collapsed");
+    }
+    else
+        elt.setAttribute("collapsed", collapsed ? "true" : "false");
+};
+
+this.obscure = function(elt, obscured)
+{
+    if (obscured)
+        this.setClass(elt, "obscured");
+    else
+        this.removeClass(elt, "obscured");
+};
+
+this.hide = function(elt, hidden)
+{
+    elt.style.visibility = hidden ? "hidden" : "visible";
+};
+
+this.clearNode = function(node)
+{
+    var nodeName = " " + node.nodeName.toLowerCase() + " ";
+    var ignoreTags = " table tbody thead tfoot th tr td ";
+
+    // IE can't use innerHTML of table elements
+    if (this.isIE && ignoreTags.indexOf(nodeName) != -1)
+        this.eraseNode(node);
+    else
+        node.innerHTML = "";
+};
+
+this.eraseNode = function(node)
+{
+    while (node.lastChild)
+        node.removeChild(node.lastChild);
+};
+
+// ************************************************************************************************
+// Window iteration
+
+this.iterateWindows = function(win, handler)
+{
+    if (!win || !win.document)
+        return;
+
+    handler(win);
+
+    if (win == top || !win.frames) return; // XXXjjb hack for chromeBug
+
+    for (var i = 0; i < win.frames.length; ++i)
+    {
+        var subWin = win.frames[i];
+        if (subWin != win)
+            this.iterateWindows(subWin, handler);
+    }
+};
+
+this.getRootWindow = function(win)
+{
+    for (; win; win = win.parent)
+    {
+        if (!win.parent || win == win.parent || !this.instanceOf(win.parent, "Window"))
+            return win;
+    }
+    return null;
+};
+
+// ************************************************************************************************
+// Graphics
+
+this.getClientOffset = function(elt)
+{
+    var addOffset = function addOffset(elt, coords, view)
+    {
+        var p = elt.offsetParent;
+
+        ///var style = isIE ? elt.currentStyle : view.getComputedStyle(elt, "");
+        var chrome = Firebug.chrome;
+
+        if (elt.offsetLeft)
+            ///coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth);
+            coords.x += elt.offsetLeft + chrome.getMeasurementInPixels(elt, "borderLeft");
+        if (elt.offsetTop)
+            ///coords.y += elt.offsetTop + parseInt(style.borderTopWidth);
+            coords.y += elt.offsetTop + chrome.getMeasurementInPixels(elt, "borderTop");
+
+        if (p)
+        {
+            if (p.nodeType == 1)
+                addOffset(p, coords, view);
+        }
+        else
+        {
+            var otherView = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView;
+            // IE will fail when reading the frameElement property of a popup window.
+            // We don't need it anyway once it is outside the (popup) viewport, so we're
+            // ignoring the frameElement check when the window is a popup
+            if (!otherView.opener && otherView.frameElement)
+                addOffset(otherView.frameElement, coords, otherView);
+        }
+    };
+
+    var isIE = this.isIE;
+    var coords = {x: 0, y: 0};
+    if (elt)
+    {
+        var view = isIE ? elt.ownerDocument.parentWindow : elt.ownerDocument.defaultView;
+        addOffset(elt, coords, view);
+    }
+
+    return coords;
+};
+
+this.getViewOffset = function(elt, singleFrame)
+{
+    function addOffset(elt, coords, view)
+    {
+        var p = elt.offsetParent;
+        coords.x += elt.offsetLeft - (p ? p.scrollLeft : 0);
+        coords.y += elt.offsetTop - (p ? p.scrollTop : 0);
+
+        if (p)
+        {
+            if (p.nodeType == 1)
+            {
+                var parentStyle = view.getComputedStyle(p, "");
+                if (parentStyle.position != "static")
+                {
+                    coords.x += parseInt(parentStyle.borderLeftWidth);
+                    coords.y += parseInt(parentStyle.borderTopWidth);
+
+                    if (p.localName == "TABLE")
+                    {
+                        coords.x += parseInt(parentStyle.paddingLeft);
+                        coords.y += parseInt(parentStyle.paddingTop);
+                    }
+                    else if (p.localName == "BODY")
+                    {
+                        var style = view.getComputedStyle(elt, "");
+                        coords.x += parseInt(style.marginLeft);
+                        coords.y += parseInt(style.marginTop);
+                    }
+                }
+                else if (p.localName == "BODY")
+                {
+                    coords.x += parseInt(parentStyle.borderLeftWidth);
+                    coords.y += parseInt(parentStyle.borderTopWidth);
+                }
+
+                var parent = elt.parentNode;
+                while (p != parent)
+                {
+                    coords.x -= parent.scrollLeft;
+                    coords.y -= parent.scrollTop;
+                    parent = parent.parentNode;
+                }
+                addOffset(p, coords, view);
+            }
+        }
+        else
+        {
+            if (elt.localName == "BODY")
+            {
+                var style = view.getComputedStyle(elt, "");
+                coords.x += parseInt(style.borderLeftWidth);
+                coords.y += parseInt(style.borderTopWidth);
+
+                var htmlStyle = view.getComputedStyle(elt.parentNode, "");
+                coords.x -= parseInt(htmlStyle.paddingLeft);
+                coords.y -= parseInt(htmlStyle.paddingTop);
+            }
+
+            if (elt.scrollLeft)
+                coords.x += elt.scrollLeft;
+            if (elt.scrollTop)
+                coords.y += elt.scrollTop;
+
+            var win = elt.ownerDocument.defaultView;
+            if (win && (!singleFrame && win.frameElement))
+                addOffset(win.frameElement, coords, win);
+        }
+
+    }
+
+    var coords = {x: 0, y: 0};
+    if (elt)
+        addOffset(elt, coords, elt.ownerDocument.defaultView);
+
+    return coords;
+};
+
+this.getLTRBWH = function(elt)
+{
+    var bcrect,
+        dims = {"left": 0, "top": 0, "right": 0, "bottom": 0, "width": 0, "height": 0};
+
+    if (elt)
+    {
+        bcrect = elt.getBoundingClientRect();
+        dims.left = bcrect.left;
+        dims.top = bcrect.top;
+        dims.right = bcrect.right;
+        dims.bottom = bcrect.bottom;
+
+        if(bcrect.width)
+        {
+            dims.width = bcrect.width;
+            dims.height = bcrect.height;
+        }
+        else
+        {
+            dims.width = dims.right - dims.left;
+            dims.height = dims.bottom - dims.top;
+        }
+    }
+    return dims;
+};
+
+this.applyBodyOffsets = function(elt, clientRect)
+{
+    var od = elt.ownerDocument;
+    if (!od.body)
+        return clientRect;
+
+    var style = od.defaultView.getComputedStyle(od.body, null);
+
+    var pos = style.getPropertyValue('position');
+    if(pos === 'absolute' || pos === 'relative')
+    {
+        var borderLeft = parseInt(style.getPropertyValue('border-left-width').replace('px', ''),10) || 0;
+        var borderTop = parseInt(style.getPropertyValue('border-top-width').replace('px', ''),10) || 0;
+        var paddingLeft = parseInt(style.getPropertyValue('padding-left').replace('px', ''),10) || 0;
+        var paddingTop = parseInt(style.getPropertyValue('padding-top').replace('px', ''),10) || 0;
+        var marginLeft = parseInt(style.getPropertyValue('margin-left').replace('px', ''),10) || 0;
+        var marginTop = parseInt(style.getPropertyValue('margin-top').replace('px', ''),10) || 0;
+
+        var offsetX = borderLeft + paddingLeft + marginLeft;
+        var offsetY = borderTop + paddingTop + marginTop;
+
+        clientRect.left -= offsetX;
+        clientRect.top -= offsetY;
+        clientRect.right -= offsetX;
+        clientRect.bottom -= offsetY;
+    }
+
+    return clientRect;
+};
+
+this.getOffsetSize = function(elt)
+{
+    return {width: elt.offsetWidth, height: elt.offsetHeight};
+};
+
+this.getOverflowParent = function(element)
+{
+    for (var scrollParent = element.parentNode; scrollParent; scrollParent = scrollParent.offsetParent)
+    {
+        if (scrollParent.scrollHeight > scrollParent.offsetHeight)
+            return scrollParent;
+    }
+};
+
+this.isScrolledToBottom = function(element)
+{
+    var onBottom = (element.scrollTop + element.offsetHeight) == element.scrollHeight;
+    if (FBTrace.DBG_CONSOLE)
+        FBTrace.sysout("isScrolledToBottom offsetHeight: "+element.offsetHeight +" onBottom:"+onBottom);
+    return onBottom;
+};
+
+this.scrollToBottom = function(element)
+{
+        element.scrollTop = element.scrollHeight;
+
+        if (FBTrace.DBG_CONSOLE)
+        {
+            FBTrace.sysout("scrollToBottom reset scrollTop "+element.scrollTop+" = "+element.scrollHeight);
+            if (element.scrollHeight == element.offsetHeight)
+                FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element "+element, element);
+        }
+
+        return (element.scrollTop == element.scrollHeight);
+};
+
+this.move = function(element, x, y)
+{
+    element.style.left = x + "px";
+    element.style.top = y + "px";
+};
+
+this.resize = function(element, w, h)
+{
+    element.style.width = w + "px";
+    element.style.height = h + "px";
+};
+
+this.linesIntoCenterView = function(element, scrollBox)  // {before: int, after: int}
+{
+    if (!scrollBox)
+        scrollBox = this.getOverflowParent(element);
+
+    if (!scrollBox)
+        return;
+
+    var offset = this.getClientOffset(element);
+
+    var topSpace = offset.y - scrollBox.scrollTop;
+    var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight)
+            - (offset.y + element.offsetHeight);
+
+    if (topSpace < 0 || bottomSpace < 0)
+    {
+        var split = (scrollBox.clientHeight/2);
+        var centerY = offset.y - split;
+        scrollBox.scrollTop = centerY;
+        topSpace = split;
+        bottomSpace = split -  element.offsetHeight;
+    }
+
+    return {before: Math.round((topSpace/element.offsetHeight) + 0.5),
+            after: Math.round((bottomSpace/element.offsetHeight) + 0.5) };
+};
+
+this.scrollIntoCenterView = function(element, scrollBox, notX, notY)
+{
+    if (!element)
+        return;
+
+    if (!scrollBox)
+        scrollBox = this.getOverflowParent(element);
+
+    if (!scrollBox)
+        return;
+
+    var offset = this.getClientOffset(element);
+
+    if (!notY)
+    {
+        var topSpace = offset.y - scrollBox.scrollTop;
+        var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight)
+            - (offset.y + element.offsetHeight);
+
+        if (topSpace < 0 || bottomSpace < 0)
+        {
+            var centerY = offset.y - (scrollBox.clientHeight/2);
+            scrollBox.scrollTop = centerY;
+        }
+    }
+
+    if (!notX)
+    {
+        var leftSpace = offset.x - scrollBox.scrollLeft;
+        var rightSpace = (scrollBox.scrollLeft + scrollBox.clientWidth)
+            - (offset.x + element.clientWidth);
+
+        if (leftSpace < 0 || rightSpace < 0)
+        {
+            var centerX = offset.x - (scrollBox.clientWidth/2);
+            scrollBox.scrollLeft = centerX;
+        }
+    }
+    if (FBTrace.DBG_SOURCEFILES)
+        FBTrace.sysout("lib.scrollIntoCenterView ","Element:"+element.innerHTML);
+};
+
+
+// ************************************************************************************************
+// CSS
+
+var cssKeywordMap = null;
+var cssPropNames = null;
+var cssColorNames = null;
+var imageRules = null;
+
+this.getCSSKeywordsByProperty = function(propName)
+{
+    if (!cssKeywordMap)
+    {
+        cssKeywordMap = {};
+
+        for (var name in this.cssInfo)
+        {
+            var list = [];
+
+            var types = this.cssInfo[name];
+            for (var i = 0; i < types.length; ++i)
+            {
+                var keywords = this.cssKeywords[types[i]];
+                if (keywords)
+                    list.push.apply(list, keywords);
+            }
+
+            cssKeywordMap[name] = list;
+        }
+    }
+
+    return propName in cssKeywordMap ? cssKeywordMap[propName] : [];
+};
+
+this.getCSSPropertyNames = function()
+{
+    if (!cssPropNames)
+    {
+        cssPropNames = [];
+
+        for (var name in this.cssInfo)
+            cssPropNames.push(name);
+    }
+
+    return cssPropNames;
+};
+
+this.isColorKeyword = function(keyword)
+{
+    if (keyword == "transparent")
+        return false;
+
+    if (!cssColorNames)
+    {
+        cssColorNames = [];
+
+        var colors = this.cssKeywords["color"];
+        for (var i = 0; i < colors.length; ++i)
+            cssColorNames.push(colors[i].toLowerCase());
+
+        var systemColors = this.cssKeywords["systemColor"];
+        for (var i = 0; i < systemColors.length; ++i)
+            cssColorNames.push(systemColors[i].toLowerCase());
+    }
+
+    return cssColorNames.indexOf ? // Array.indexOf is not available in IE
+            cssColorNames.indexOf(keyword.toLowerCase()) != -1 :
+            (" " + cssColorNames.join(" ") + " ").indexOf(" " + keyword.toLowerCase() + " ") != -1;
+};
+
+this.isImageRule = function(rule)
+{
+    if (!imageRules)
+    {
+        imageRules = [];
+
+        for (var i in this.cssInfo)
+        {
+            var r = i.toLowerCase();
+            var suffix = "image";
+            if (r.match(suffix + "$") == suffix || r == "background")
+                imageRules.push(r);
+        }
+    }
+
+    return imageRules.indexOf ? // Array.indexOf is not available in IE
+            imageRules.indexOf(rule.toLowerCase()) != -1 :
+            (" " + imageRules.join(" ") + " ").indexOf(" " + rule.toLowerCase() + " ") != -1;
+};
+
+this.copyTextStyles = function(fromNode, toNode, style)
+{
+    var view = this.isIE ?
+            fromNode.ownerDocument.parentWindow :
+            fromNode.ownerDocument.defaultView;
+
+    if (view)
+    {
+        if (!style)
+            style = this.isIE ? fromNode.currentStyle : view.getComputedStyle(fromNode, "");
+
+        toNode.style.fontFamily = style.fontFamily;
+
+        // TODO: xxxpedro need to create a FBL.getComputedStyle() because IE
+        // returns wrong computed styles for inherited properties (like font-*)
+        //
+        // Also would be good to create a FBL.getStyle()
+        toNode.style.fontSize = style.fontSize;
+        toNode.style.fontWeight = style.fontWeight;
+        toNode.style.fontStyle = style.fontStyle;
+
+        return style;
+    }
+};
+
+this.copyBoxStyles = function(fromNode, toNode, style)
+{
+    var view = this.isIE ?
+            fromNode.ownerDocument.parentWindow :
+            fromNode.ownerDocument.defaultView;
+
+    if (view)
+    {
+        if (!style)
+            style = this.isIE ? fromNode.currentStyle : view.getComputedStyle(fromNode, "");
+
+        toNode.style.marginTop = style.marginTop;
+        toNode.style.marginRight = style.marginRight;
+        toNode.style.marginBottom = style.marginBottom;
+        toNode.style.marginLeft = style.marginLeft;
+        toNode.style.borderTopWidth = style.borderTopWidth;
+        toNode.style.borderRightWidth = style.borderRightWidth;
+        toNode.style.borderBottomWidth = style.borderBottomWidth;
+        toNode.style.borderLeftWidth = style.borderLeftWidth;
+
+        return style;
+    }
+};
+
+this.readBoxStyles = function(style)
+{
+    var styleNames = {
+        "margin-top": "marginTop", "margin-right": "marginRight",
+        "margin-left": "marginLeft", "margin-bottom": "marginBottom",
+        "border-top-width": "borderTop", "border-right-width": "borderRight",
+        "border-left-width": "borderLeft", "border-bottom-width": "borderBottom",
+        "padding-top": "paddingTop", "padding-right": "paddingRight",
+        "padding-left": "paddingLeft", "padding-bottom": "paddingBottom",
+        "z-index": "zIndex"
+    };
+
+    var styles = {};
+    for (var styleName in styleNames)
+        styles[styleNames[styleName]] = parseInt(style.getPropertyCSSValue(styleName).cssText) || 0;
+    if (FBTrace.DBG_INSPECT)
+        FBTrace.sysout("readBoxStyles ", styles);
+    return styles;
+};
+
+this.getBoxFromStyles = function(style, element)
+{
+    var args = this.readBoxStyles(style);
+    args.width = element.offsetWidth
+        - (args.paddingLeft+args.paddingRight+args.borderLeft+args.borderRight);
+    args.height = element.offsetHeight
+        - (args.paddingTop+args.paddingBottom+args.borderTop+args.borderBottom);
+    return args;
+};
+
+this.getElementCSSSelector = function(element)
+{
+    var label = element.localName.toLowerCase();
+    if (element.id)
+        label += "#" + element.id;
+    if (element.hasAttribute("class"))
+        label += "." + element.getAttribute("class").split(" ")[0];
+
+    return label;
+};
+
+this.getURLForStyleSheet= function(styleSheet)
+{
+    //http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet. For inline style sheets, the value of this attribute is null.
+    return (styleSheet.href ? styleSheet.href : styleSheet.ownerNode.ownerDocument.URL);
+};
+
+this.getDocumentForStyleSheet = function(styleSheet)
+{
+    while (styleSheet.parentStyleSheet && !styleSheet.ownerNode)
+    {
+        styleSheet = styleSheet.parentStyleSheet;
+    }
+    if (styleSheet.ownerNode)
+      return styleSheet.ownerNode.ownerDocument;
+};
+
+/**
+ * Retrieves the instance number for a given style sheet. The instance number
+ * is sheet's index within the set of all other sheets whose URL is the same.
+ */
+this.getInstanceForStyleSheet = function(styleSheet, ownerDocument)
+{
+    // System URLs are always unique (or at least we are making this assumption)
+    if (FBL.isSystemStyleSheet(styleSheet))
+        return 0;
+
+    // ownerDocument is an optional hint for performance
+    if (FBTrace.DBG_CSS) FBTrace.sysout("getInstanceForStyleSheet: " + styleSheet.href + " " + styleSheet.media.mediaText + " " + (styleSheet.ownerNode && FBL.getElementXPath(styleSheet.ownerNode)), ownerDocument);
+    ownerDocument = ownerDocument || FBL.getDocumentForStyleSheet(styleSheet);
+
+    var ret = 0,
+        styleSheets = ownerDocument.styleSheets,
+        href = styleSheet.href;
+    for (var i = 0; i < styleSheets.length; i++)
+    {
+        var curSheet = styleSheets[i];
+        if (FBTrace.DBG_CSS) FBTrace.sysout("getInstanceForStyleSheet: compare href " + i + " " + curSheet.href + " " + curSheet.media.mediaText + " " + (curSheet.ownerNode && FBL.getElementXPath(curSheet.ownerNode)));
+        if (curSheet == styleSheet)
+            break;
+        if (curSheet.href == href)
+            ret++;
+    }
+    return ret;
+};
+
+// ************************************************************************************************
+// HTML and XML Serialization
+
+
+var getElementType = this.getElementType = function(node)
+{
+    if (isElementXUL(node))
+        return 'xul';
+    else if (isElementSVG(node))
+        return 'svg';
+    else if (isElementMathML(node))
+        return 'mathml';
+    else if (isElementXHTML(node))
+        return 'xhtml';
+    else if (isElementHTML(node))
+        return 'html';
+};
+
+var getElementSimpleType = this.getElementSimpleType = function(node)
+{
+    if (isElementSVG(node))
+        return 'svg';
+    else if (isElementMathML(node))
+        return 'mathml';
+    else
+        return 'html';
+};
+
+var isElementHTML = this.isElementHTML = function(node)
+{
+    return node.nodeName == node.nodeName.toUpperCase();
+};
+
+var isElementXHTML = this.isElementXHTML = function(node)
+{
+    return node.nodeName == node.nodeName.toLowerCase();
+};
+
+var isElementMathML = this.isElementMathML = function(node)
+{
+    return node.namespaceURI == 'http://www.w3.org/1998/Math/MathML';
+};
+
+var isElementSVG = this.isElementSVG = function(node)
+{
+    return node.namespaceURI == 'http://www.w3.org/2000/svg';
+};
+
+var isElementXUL = this.isElementXUL = function(node)
+{
+    return node instanceof XULElement;
+};
+
+this.isSelfClosing = function(element)
+{
+    if (isElementSVG(element) || isElementMathML(element))
+        return true;
+    var tag = element.localName.toLowerCase();
+    return (this.selfClosingTags.hasOwnProperty(tag));
+};
+
+this.getElementHTML = function(element)
+{
+    var self=this;
+    function toHTML(elt)
+    {
+        if (elt.nodeType == Node.ELEMENT_NODE)
+        {
+            if (unwrapObject(elt).firebugIgnore)
+                return;
+
+            html.push('<', elt.nodeName.toLowerCase());
+
+            for (var i = 0; i < elt.attributes.length; ++i)
+            {
+                var attr = elt.attributes[i];
+
+                // Hide attributes set by Firebug
+                if (attr.localName.indexOf("firebug-") == 0)
+                    continue;
+
+                // MathML
+                if (attr.localName.indexOf("-moz-math") == 0)
+                {
+                    // just hide for now
+                    continue;
+                }
+
+                html.push(' ', attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue),'"');
+            }
+
+            if (elt.firstChild)
+            {
+                html.push('>');
+
+                var pureText=true;
+                for (var child = element.firstChild; child; child = child.nextSibling)
+                    pureText=pureText && (child.nodeType == Node.TEXT_NODE);
+
+                if (pureText)
+                    html.push(escapeForHtmlEditor(elt.textContent));
+                else {
+                    for (var child = elt.firstChild; child; child = child.nextSibling)
+                        toHTML(child);
+                }
+
+                html.push('</', elt.nodeName.toLowerCase(), '>');
+            }
+            else if (isElementSVG(elt) || isElementMathML(elt))
+            {
+                html.push('/>');
+            }
+            else if (self.isSelfClosing(elt))
+            {
+                html.push((isElementXHTML(elt))?'/>':'>');
+            }
+            else
+            {
+                html.push('></', elt.nodeName.toLowerCase(), '>');
+            }
+        }
+        else if (elt.nodeType == Node.TEXT_NODE)
+            html.push(escapeForTextNode(elt.textContent));
+        else if (elt.nodeType == Node.CDATA_SECTION_NODE)
+            html.push('<![CDATA[', elt.nodeValue, ']]>');
+        else if (elt.nodeType == Node.COMMENT_NODE)
+            html.push('<!--', elt.nodeValue, '-->');
+    }
+
+    var html = [];
+    toHTML(element);
+    return html.join("");
+};
+
+this.getElementXML = function(element)
+{
+    function toXML(elt)
+    {
+        if (elt.nodeType == Node.ELEMENT_NODE)
+        {
+            if (unwrapObject(elt).firebugIgnore)
+                return;
+
+            xml.push('<', elt.nodeName.toLowerCase());
+
+            for (var i = 0; i < elt.attributes.length; ++i)
+            {
+                var attr = elt.attributes[i];
+
+                // Hide attributes set by Firebug
+                if (attr.localName.indexOf("firebug-") == 0)
+                    continue;
+
+                // MathML
+                if (attr.localName.indexOf("-moz-math") == 0)
+                {
+                    // just hide for now
+                    continue;
+                }
+
+                xml.push(' ', attr.nodeName, '="', escapeForElementAttribute(attr.nodeValue),'"');
+            }
+
+            if (elt.firstChild)
+            {
+                xml.push('>');
+
+                for (var child = elt.firstChild; child; child = child.nextSibling)
+                    toXML(child);
+
+                xml.push('</', elt.nodeName.toLowerCase(), '>');
+            }
+            else
+                xml.push('/>');
+        }
+        else if (elt.nodeType == Node.TEXT_NODE)
+            xml.push(elt.nodeValue);
+        else if (elt.nodeType == Node.CDATA_SECTION_NODE)
+            xml.push('<![CDATA[', elt.nodeValue, ']]>');
+        else if (elt.nodeType == Node.COMMENT_NODE)
+            xml.push('<!--', elt.nodeValue, '-->');
+    }
+
+    var xml = [];
+    toXML(element);
+    return xml.join("");
+};
+
+
+// ************************************************************************************************
+// CSS classes
+
+this.hasClass = function(node, name) // className, className, ...
+{
+    // TODO: xxxpedro when lib.hasClass is called with more than 2 arguments?
+    // this function can be optimized a lot if assumed 2 arguments only,
+    // which seems to be what happens 99% of the time
+    if (arguments.length == 2)
+        return (' '+node.className+' ').indexOf(' '+name+' ') != -1;
+
+    if (!node || node.nodeType != 1)
+        return false;
+    else
+    {
+        for (var i=1; i<arguments.length; ++i)
+        {
+            var name = arguments[i];
+            var re = new RegExp("(^|\\s)"+name+"($|\\s)");
+            if (!re.exec(node.className))
+                return false;
+        }
+
+        return true;
+    }
+};
+
+this.old_hasClass = function(node, name) // className, className, ...
+{
+    if (!node || node.nodeType != 1)
+        return false;
+    else
+    {
+        for (var i=1; i<arguments.length; ++i)
+        {
+            var name = arguments[i];
+            var re = new RegExp("(^|\\s)"+name+"($|\\s)");
+            if (!re.exec(node.className))
+                return false;
+        }
+
+        return true;
+    }
+};
+
+this.setClass = function(node, name)
+{
+    if (node && (' '+node.className+' ').indexOf(' '+name+' ') == -1)
+    ///if (node && !this.hasClass(node, name))
+        node.className += " " + name;
+};
+
+this.getClassValue = function(node, name)
+{
+    var re = new RegExp(name+"-([^ ]+)");
+    var m = re.exec(node.className);
+    return m ? m[1] : "";
+};
+
+this.removeClass = function(node, name)
+{
+    if (node && node.className)
+    {
+        var index = node.className.indexOf(name);
+        if (index >= 0)
+        {
+            var size = name.length;
+            node.className = node.className.substr(0,index-1) + node.className.substr(index+size);
+        }
+    }
+};
+
+this.toggleClass = function(elt, name)
+{
+    if ((' '+elt.className+' ').indexOf(' '+name+' ') != -1)
+    ///if (this.hasClass(elt, name))
+        this.removeClass(elt, name);
+    else
+        this.setClass(elt, name);
+};
+
+this.setClassTimed = function(elt, name, context, timeout)
+{
+    if (!timeout)
+        timeout = 1300;
+
+    if (elt.__setClassTimeout)
+        context.clearTimeout(elt.__setClassTimeout);
+    else
+        this.setClass(elt, name);
+
+    elt.__setClassTimeout = context.setTimeout(function()
+    {
+        delete elt.__setClassTimeout;
+
+        FBL.removeClass(elt, name);
+    }, timeout);
+};
+
+this.cancelClassTimed = function(elt, name, context)
+{
+    if (elt.__setClassTimeout)
+    {
+        FBL.removeClass(elt, name);
+        context.clearTimeout(elt.__setClassTimeout);
+        delete elt.__setClassTimeout;
+    }
+};
+
+
+// ************************************************************************************************
+// DOM queries
+
+this.$ = function(id, doc)
+{
+    if (doc)
+        return doc.getElementById(id);
+    else
+    {
+        return FBL.Firebug.chrome.document.getElementById(id);
+    }
+};
+
+this.$$ = function(selector, doc)
+{
+    if (doc || !FBL.Firebug.chrome)
+        return FBL.Firebug.Selector(selector, doc);
+    else
+    {
+        return FBL.Firebug.Selector(selector, FBL.Firebug.chrome.document);
+    }
+};
+
+this.getChildByClass = function(node) // ,classname, classname, classname...
+{
+    for (var i = 1; i < arguments.length; ++i)
+    {
+        var className = arguments[i];
+        var child = node.firstChild;
+        node = null;
+        for (; child; child = child.nextSibling)
+        {
+            if (this.hasClass(child, className))
+            {
+                node = child;
+                break;
+            }
+        }
+    }
+
+    return node;
+};
+
+this.getAncestorByClass = function(node, className)
+{
+    for (var parent = node; parent; parent = parent.parentNode)
+    {
+        if (this.hasClass(parent, className))
+            return parent;
+    }
+
+    return null;
+};
+
+
+this.getElementsByClass = function(node, className)
+{
+    var result = [];
+
+    for (var child = node.firstChild; child; child = child.nextSibling)
+    {
+        if (this.hasClass(child, className))
+            result.push(child);
+    }
+
+    return result;
+};
+
+this.getElementByClass = function(node, className)  // className, className, ...
+{
+    var args = cloneArray(arguments); args.splice(0, 1);
+    for (var child = node.firstChild; child; child = child.nextSibling)
+    {
+        var args1 = cloneArray(args); args1.unshift(child);
+        if (FBL.hasClass.apply(null, args1))
+            return child;
+        else
+        {
+            var found = FBL.getElementByClass.apply(null, args1);
+            if (found)
+                return found;
+        }
+    }
+
+    return null;
+};
+
+this.isAncestor = function(node, potentialAncestor)
+{
+    for (var parent = node; parent; parent = parent.parentNode)
+    {
+        if (parent == potentialAncestor)
+            return true;
+    }
+
+    return false;
+};
+
+this.getNextElement = function(node)
+{
+    while (node && node.nodeType != 1)
+        node = node.nextSibling;
+
+    return node;
+};
+
+this.getPreviousElement = function(node)
+{
+    while (node && node.nodeType != 1)
+        node = node.previousSibling;
+
+    return node;
+};
+
+this.getBody = function(doc)
+{
+    if (doc.body)
+        return doc.body;
+
+    var body = doc.getElementsByTagName("body")[0];
+    if (body)
+        return body;
+
+    return doc.firstChild;  // For non-HTML docs
+};
+
+this.findNextDown = function(node, criteria)
+{
+    if (!node)
+        return null;
+
+    for (var child = node.firstChild; child; child = child.nextSibling)
+    {
+        if (criteria(child))
+            return child;
+
+        var next = this.findNextDown(child, criteria);
+        if (next)
+            return next;
+    }
+};
+
+this.findPreviousUp = function(node, criteria)
+{
+    if (!node)
+        return null;
+
+    for (var child = node.lastChild; child; child = child.previousSibling)
+    {
+        var next = this.findPreviousUp(child, criteria);
+        if (next)
+            return next;
+
+        if (criteria(child))
+            return child;
+    }
+};
+
+this.findNext = function(node, criteria, upOnly, maxRoot)
+{
+    if (!node)
+        return null;
+
+    if (!upOnly)
+    {
+        var next = this.findNextDown(node, criteria);
+        if (next)
+            return next;
+    }
+
+    for (var sib = node.nextSibling; sib; sib = sib.nextSibling)
+    {
+        if (criteria(sib))
+            return sib;
+
+        var next = this.findNextDown(sib, criteria);
+        if (next)
+            return next;
+    }
+
+    if (node.parentNode && node.parentNode != maxRoot)
+        return this.findNext(node.parentNode, criteria, true);
+};
+
+this.findPrevious = function(node, criteria, downOnly, maxRoot)
+{
+    if (!node)
+        return null;
+
+    for (var sib = node.previousSibling; sib; sib = sib.previousSibling)
+    {
+        var prev = this.findPreviousUp(sib, criteria);
+        if (prev)
+            return prev;
+
+        if (criteria(sib))
+            return sib;
+    }
+
+    if (!downOnly)
+    {
+        var next = this.findPreviousUp(node, criteria);
+        if (next)
+            return next;
+    }
+
+    if (node.parentNode && node.parentNode != maxRoot)
+    {
+        if (criteria(node.parentNode))
+            return node.parentNode;
+
+        return this.findPrevious(node.parentNode, criteria, true);
+    }
+};
+
+this.getNextByClass = function(root, state)
+{
+    var iter = function iter(node) { return node.nodeType == 1 && FBL.hasClass(node, state); };
+    return this.findNext(root, iter);
+};
+
+this.getPreviousByClass = function(root, state)
+{
+    var iter = function iter(node) { return node.nodeType == 1 && FBL.hasClass(node, state); };
+    return this.findPrevious(root, iter);
+};
+
+this.isElement = function(o)
+{
+    try {
+        return o && this.instanceOf(o, "Element");
+    }
+    catch (ex) {
+        return false;
+    }
+};
+
+
+// ************************************************************************************************
+// DOM Modification
+
+// TODO: xxxpedro use doc fragments in Context API
+var appendFragment = null;
+
+this.appendInnerHTML = function(element, html, referenceElement)
+{
+    // if undefined, we must convert it to null otherwise it will throw an error in IE
+    // when executing element.insertBefore(firstChild, referenceElement)
+    referenceElement = referenceElement || null;
+
+    var doc = element.ownerDocument;
+
+    // doc.createRange not available in IE
+    if (doc.createRange)
+    {
+        var range = doc.createRange();  // a helper object
+        range.selectNodeContents(element); // the environment to interpret the html
+
+        var fragment = range.createContextualFragment(html);  // parse
+        var firstChild = fragment.firstChild;
+        element.insertBefore(fragment, referenceElement);
+    }
+    else
+    {
+        if (!appendFragment || appendFragment.ownerDocument != doc)
+            appendFragment = doc.createDocumentFragment();
+
+        var div = doc.createElement("div");
+        div.innerHTML = html;
+
+        var firstChild = div.firstChild;
+        while (div.firstChild)
+            appendFragment.appendChild(div.firstChild);
+
+        element.insertBefore(appendFragment, referenceElement);
+
+        div = null;
+    }
+
+    return firstChild;
+};
+
+
+// ************************************************************************************************
+// DOM creation
+
+this.createElement = function(tagName, properties)
+{
+    properties = properties || {};
+    var doc = properties.document || FBL.Firebug.chrome.document;
+
+    var element = doc.createElement(tagName);
+
+    for(var name in properties)
+    {
+        if (name != "document")
+        {
+            element[name] = properties[name];
+        }
+    }
+
+    return element;
+};
+
+this.createGlobalElement = function(tagName, properties)
+{
+    properties = properties || {};
+    var doc = FBL.Env.browser.document;
+
+    var element = this.NS && doc.createElementNS ?
+            doc.createElementNS(FBL.NS, tagName) :
+            doc.createElement(tagName);
+
+    for(var name in properties)
+    {
+        var propname = name;
+        if (FBL.isIE && name == "class") propname = "className";
+
+        if (name != "document")
+        {
+            element.setAttribute(propname, properties[name]);
+        }
+    }
+
+    return element;
+};
+
+//************************************************************************************************
+
+this.safeGetWindowLocation = function(window)
+{
+    try
+    {
+        if (window)
+        {
+            if (window.closed)
+                return "(window.closed)";
+            if ("location" in window)
+                return window.location+"";
+            else
+                return "(no window.location)";
+        }
+        else
+            return "(no context.window)";
+    }
+    catch(exc)
+    {
+        if (FBTrace.DBG_WINDOWS || FBTrace.DBG_ERRORS)
+            FBTrace.sysout("TabContext.getWindowLocation failed "+exc, exc);
+            FBTrace.sysout("TabContext.getWindowLocation failed window:", window);
+        return "(getWindowLocation: "+exc+")";
+    }
+};
+
+// ************************************************************************************************
+// Events
+
+this.isLeftClick = function(event)
+{
+    return (this.isIE && event.type != "click" && event.type != "dblclick" ?
+            event.button == 1 : // IE "click" and "dblclick" button model
+            event.button == 0) && // others
+        this.noKeyModifiers(event);
+};
+
+this.isMiddleClick = function(event)
+{
+    return (this.isIE && event.type != "click" && event.type != "dblclick" ?
+            event.button == 4 : // IE "click" and "dblclick" button model
+            event.button == 1) &&
+        this.noKeyModifiers(event);
+};
+
+this.isRightClick = function(event)
+{
+    return (this.isIE && event.type != "click" && event.type != "dblclick" ?
+            event.button == 2 : // IE "click" and "dblclick" button model
+            event.button == 2) &&
+        this.noKeyModifiers(event);
+};
+
+this.noKeyModifiers = function(event)
+{
+    return !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey;
+};
+
+this.isControlClick = function(event)
+{
+    return (this.isIE && event.type != "click" && event.type != "dblclick" ?
+            event.button == 1 : // IE "click" and "dblclick" button model
+            event.button == 0) &&
+        this.isControl(event);
+};
+
+this.isShiftClick = function(event)
+{
+    return (this.isIE && event.type != "click" && event.type != "dblclick" ?
+            event.button == 1 : // IE "click" and "dblclick" button model
+            event.button == 0) &&
+        this.isShift(event);
+};
+
+this.isControl = function(event)
+{
+    return (event.metaKey || event.ctrlKey) && !event.shiftKey && !event.altKey;
+};
+
+this.isAlt = function(event)
+{
+    return event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey;
+};
+
+this.isAltClick = function(event)
+{
+    return (this.isIE && event.type != "click" && event.type != "dblclick" ?
+            event.button == 1 : // IE "click" and "dblclick" button model
+            event.button == 0) &&
+        this.isAlt(event);
+};
+
+this.isControlShift = function(event)
+{
+    return (event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey;
+};
+
+this.isShift = function(event)
+{
+    return event.shiftKey && !event.metaKey && !event.ctrlKey && !event.altKey;
+};
+
+this.addEvent = function(object, name, handler, useCapture)
+{
+    if (object.addEventListener)
+        object.addEventListener(name, handler, useCapture);
+    else
+        object.attachEvent("on"+name, handler);
+};
+
+this.removeEvent = function(object, name, handler, useCapture)
+{
+    try
+    {
+        if (object.removeEventListener)
+            object.removeEventListener(name, handler, useCapture);
+        else
+            object.detachEvent("on"+name, handler);
+    }
+    catch(e)
+    {
+        if (FBTrace.DBG_ERRORS)
+            FBTrace.sysout("FBL.removeEvent error: ", object, name);
+    }
+};
+
+this.cancelEvent = function(e, preventDefault)
+{
+    if (!e) return;
+
+    if (preventDefault)
+    {
+                if (e.preventDefault)
+                    e.preventDefault();
+                else
+                    e.returnValue = false;
+    }
+
+    if (e.stopPropagation)
+        e.stopPropagation();
+    else
+        e.cancelBubble = true;
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.addGlobalEvent = function(name, handler)
+{
+    var doc = this.Firebug.browser.document;
+    var frames = this.Firebug.browser.window.frames;
+
+    this.addEvent(doc, name, handler);
+
+    if (this.Firebug.chrome.type == "popup")
+        this.addEvent(this.Firebug.chrome.document, name, handler);
+
+    for (var i = 0, frame; frame = frames[i]; i++)
+    {
+        try
+        {
+            this.addEvent(frame.document, name, handler);
+        }
+        catch(E)
+        {
+            // Avoid acess denied
+        }
+    }
+};
+
+this.removeGlobalEvent = function(name, handler)
+{
+    var doc = this.Firebug.browser.document;
+    var frames = this.Firebug.browser.window.frames;
+
+    this.removeEvent(doc, name, handler);
+
+    if (this.Firebug.chrome.type == "popup")
+        this.removeEvent(this.Firebug.chrome.document, name, handler);
+
+    for (var i = 0, frame; frame = frames[i]; i++)
+    {
+        try
+        {
+            this.removeEvent(frame.document, name, handler);
+        }
+        catch(E)
+        {
+            // Avoid acess denied
+        }
+    }
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.dispatch = function(listeners, name, args)
+{
+    if (!listeners) return;
+
+    try
+    {/**/
+        if (typeof listeners.length != "undefined")
+        {
+            if (FBTrace.DBG_DISPATCH) FBTrace.sysout("FBL.dispatch", name+" to "+listeners.length+" listeners");
+
+            for (var i = 0; i < listeners.length; ++i)
+            {
+                var listener = listeners[i];
+                if ( listener[name] )
+                    listener[name].apply(listener, args);
+            }
+        }
+        else
+        {
+            if (FBTrace.DBG_DISPATCH) FBTrace.sysout("FBL.dispatch", name+" to listeners of an object");
+
+            for (var prop in listeners)
+            {
+                var listener = listeners[prop];
+                if ( listener[name] )
+                    listener[name].apply(listener, args);
+            }
+        }
+    }
+    catch (exc)
+    {
+        if (FBTrace.DBG_ERRORS)
+        {
+            FBTrace.sysout(" Exception in lib.dispatch "+ name, exc);
+            //FBTrace.dumpProperties(" Exception in lib.dispatch listener", listener);
+        }
+    }
+    /**/
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var disableTextSelectionHandler = function(event)
+{
+    FBL.cancelEvent(event, true);
+
+    return false;
+};
+
+this.disableTextSelection = function(e)
+{
+    if (typeof e.onselectstart != "undefined") // IE
+        this.addEvent(e, "selectstart", disableTextSelectionHandler);
+
+    else // others
+    {
+        e.style.cssText = "user-select: none; -khtml-user-select: none; -moz-user-select: none;";
+
+        // canceling the event in FF will prevent the menu popups to close when clicking over
+        // text-disabled elements
+        if (!this.isFirefox)
+            this.addEvent(e, "mousedown", disableTextSelectionHandler);
+    }
+
+    e.style.cursor = "default";
+};
+
+this.restoreTextSelection = function(e)
+{
+    if (typeof e.onselectstart != "undefined") // IE
+        this.removeEvent(e, "selectstart", disableTextSelectionHandler);
+
+    else // others
+    {
+        e.style.cssText = "cursor: default;";
+
+        // canceling the event in FF will prevent the menu popups to close when clicking over
+        // text-disabled elements
+        if (!this.isFirefox)
+            this.removeEvent(e, "mousedown", disableTextSelectionHandler);
+    }
+};
+
+// ************************************************************************************************
+// DOM Events
+
+var eventTypes =
+{
+    composition: [
+        "composition",
+        "compositionstart",
+        "compositionend" ],
+    contextmenu: [
+        "contextmenu" ],
+    drag: [
+        "dragenter",
+        "dragover",
+        "dragexit",
+        "dragdrop",
+        "draggesture" ],
+    focus: [
+        "focus",
+        "blur" ],
+    form: [
+        "submit",
+        "reset",
+        "change",
+        "select",
+        "input" ],
+    key: [
+        "keydown",
+        "keyup",
+        "keypress" ],
+    load: [
+        "load",
+        "beforeunload",
+        "unload",
+        "abort",
+        "error" ],
+    mouse: [
+        "mousedown",
+        "mouseup",
+        "click",
+        "dblclick",
+        "mouseover",
+        "mouseout",
+        "mousemove" ],
+    mutation: [
+        "DOMSubtreeModified",
+        "DOMNodeInserted",
+        "DOMNodeRemoved",
+        "DOMNodeRemovedFromDocument",
+        "DOMNodeInsertedIntoDocument",
+        "DOMAttrModified",
+        "DOMCharacterDataModified" ],
+    paint: [
+        "paint",
+        "resize",
+        "scroll" ],
+    scroll: [
+        "overflow",
+        "underflow",
+        "overflowchanged" ],
+    text: [
+        "text" ],
+    ui: [
+        "DOMActivate",
+        "DOMFocusIn",
+        "DOMFocusOut" ],
+    xul: [
+        "popupshowing",
+        "popupshown",
+        "popuphiding",
+        "popuphidden",
+        "close",
+        "command",
+        "broadcast",
+        "commandupdate" ]
+};
+
+this.getEventFamily = function(eventType)
+{
+    if (!this.families)
+    {
+        this.families = {};
+
+        for (var family in eventTypes)
+        {
+            var types = eventTypes[family];
+            for (var i = 0; i < types.length; ++i)
+                this.families[types[i]] = family;
+        }
+    }
+
+    return this.families[eventType];
+};
+
+
+// ************************************************************************************************
+// URLs
+
+this.getFileName = function(url)
+{
+    var split = this.splitURLBase(url);
+    return split.name;
+};
+
+this.splitURLBase = function(url)
+{
+    if (this.isDataURL(url))
+        return this.splitDataURL(url);
+    return this.splitURLTrue(url);
+};
+
+this.splitDataURL = function(url)
+{
+    var mark = url.indexOf(':', 3);
+    if (mark != 4)
+        return false;   //  the first 5 chars must be 'data:'
+
+    var point = url.indexOf(',', mark+1);
+    if (point < mark)
+        return false; // syntax error
+
+    var props = { encodedContent: url.substr(point+1) };
+
+    var metadataBuffer = url.substr(mark+1, point);
+    var metadata = metadataBuffer.split(';');
+    for (var i = 0; i < metadata.length; i++)
+    {
+        var nv = metadata[i].split('=');
+        if (nv.length == 2)
+            props[nv[0]] = nv[1];
+    }
+
+    // Additional Firebug-specific properties
+    if (props.hasOwnProperty('fileName'))
+    {
+         var caller_URL = decodeURIComponent(props['fileName']);
+         var caller_split = this.splitURLTrue(caller_URL);
+
+        if (props.hasOwnProperty('baseLineNumber'))  // this means it's probably an eval()
+        {
+            props['path'] = caller_split.path;
+            props['line'] = props['baseLineNumber'];
+            var hint = decodeURIComponent(props['encodedContent'].substr(0,200)).replace(/\s*$/, "");
+            props['name'] =  'eval->'+hint;
+        }
+        else
+        {
+            props['name'] = caller_split.name;
+            props['path'] = caller_split.path;
+        }
+    }
+    else
+    {
+        if (!props.hasOwnProperty('path'))
+            props['path'] = "data:";
+        if (!props.hasOwnProperty('name'))
+            props['name'] =  decodeURIComponent(props['encodedContent'].substr(0,200)).replace(/\s*$/, "");
+    }
+
+    return props;
+};
+
+this.splitURLTrue = function(url)
+{
+    var m = reSplitFile.exec(url);
+    if (!m)
+        return {name: url, path: url};
+    else if (!m[2])
+        return {path: m[1], name: m[1]};
+    else
+        return {path: m[1], name: m[2]+m[3]};
+};
+
+this.getFileExtension = function(url)
+{
+    if (!url)
+        return null;
+
+    // Remove query string from the URL if any.
+    var queryString = url.indexOf("?");
+    if (queryString != -1)
+        url = url.substr(0, queryString);
+
+    // Now get the file extension.
+    var lastDot = url.lastIndexOf(".");
+    return url.substr(lastDot+1);
+};
+
+this.isSystemURL = function(url)
+{
+    if (!url) return true;
+    if (url.length == 0) return true;
+    if (url[0] == 'h') return false;
+    if (url.substr(0, 9) == "resource:")
+        return true;
+    else if (url.substr(0, 16) == "chrome://firebug")
+        return true;
+    else if (url  == "XPCSafeJSObjectWrapper.cpp")
+        return true;
+    else if (url.substr(0, 6) == "about:")
+        return true;
+    else if (url.indexOf("firebug-service.js") != -1)
+        return true;
+    else
+        return false;
+};
+
+this.isSystemPage = function(win)
+{
+    try
+    {
+        var doc = win.document;
+        if (!doc)
+            return false;
+
+        // Detect pages for pretty printed XML
+        if ((doc.styleSheets.length && doc.styleSheets[0].href
+                == "chrome://global/content/xml/XMLPrettyPrint.css")
+            || (doc.styleSheets.length > 1 && doc.styleSheets[1].href
+                == "chrome://browser/skin/feeds/subscribe.css"))
+            return true;
+
+        return FBL.isSystemURL(win.location.href);
+    }
+    catch (exc)
+    {
+        // Sometimes documents just aren't ready to be manipulated here, but don't let that
+        // gum up the works
+        ERROR("tabWatcher.isSystemPage document not ready:"+ exc);
+        return false;
+    }
+};
+
+this.isSystemStyleSheet = function(sheet)
+{
+    var href = sheet && sheet.href;
+    return href && FBL.isSystemURL(href);
+};
+
+this.getURIHost = function(uri)
+{
+    try
+    {
+        if (uri)
+            return uri.host;
+        else
+            return "";
+    }
+    catch (exc)
+    {
+        return "";
+    }
+};
+
+this.isLocalURL = function(url)
+{
+    if (url.substr(0, 5) == "file:")
+        return true;
+    else if (url.substr(0, 8) == "wyciwyg:")
+        return true;
+    else
+        return false;
+};
+
+this.isDataURL = function(url)
+{
+    return (url && url.substr(0,5) == "data:");
+};
+
+this.getLocalPath = function(url)
+{
+    if (this.isLocalURL(url))
+    {
+        var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
+        var file = fileHandler.getFileFromURLSpec(url);
+        return file.path;
+    }
+};
+
+this.getURLFromLocalFile = function(file)
+{
+    var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
+    var URL = fileHandler.getURLSpecFromFile(file);
+    return URL;
+};
+
+this.getDataURLForContent = function(content, url)
+{
+    // data:text/javascript;fileName=x%2Cy.js;baseLineNumber=10,<the-url-encoded-data>
+    var uri = "data:text/html;";
+    uri += "fileName="+encodeURIComponent(url)+ ",";
+    uri += encodeURIComponent(content);
+    return uri;
+},
+
+this.getDomain = function(url)
+{
+    var m = /[^:]+:\/{1,3}([^\/]+)/.exec(url);
+    return m ? m[1] : "";
+};
+
+this.getURLPath = function(url)
+{
+    var m = /[^:]+:\/{1,3}[^\/]+(\/.*?)$/.exec(url);
+    return m ? m[1] : "";
+};
+
+this.getPrettyDomain = function(url)
+{
+    var m = /[^:]+:\/{1,3}(www\.)?([^\/]+)/.exec(url);
+    return m ? m[2] : "";
+};
+
+this.absoluteURL = function(url, baseURL)
+{
+    return this.absoluteURLWithDots(url, baseURL).replace("/./", "/", "g");
+};
+
+this.absoluteURLWithDots = function(url, baseURL)
+{
+    if (url[0] == "?")
+        return baseURL + url;
+
+    var reURL = /(([^:]+:)\/{1,2}[^\/]*)(.*?)$/;
+    var m = reURL.exec(url);
+    if (m)
+        return url;
+
+    var m = reURL.exec(baseURL);
+    if (!m)
+        return "";
+
+    var head = m[1];
+    var tail = m[3];
+    if (url.substr(0, 2) == "//")
+        return m[2] + url;
+    else if (url[0] == "/")
+    {
+        return head + url;
+    }
+    else if (tail[tail.length-1] == "/")
+        return baseURL + url;
+    else
+    {
+        var parts = tail.split("/");
+        return head + parts.slice(0, parts.length-1).join("/") + "/" + url;
+    }
+};
+
+this.normalizeURL = function(url)  // this gets called a lot, any performance improvement welcome
+{
+    if (!url)
+        return "";
+    // Replace one or more characters that are not forward-slash followed by /.., by space.
+    if (url.length < 255) // guard against monsters.
+    {
+        // Replace one or more characters that are not forward-slash followed by /.., by space.
+        url = url.replace(/[^\/]+\/\.\.\//, "", "g");
+        // Issue 1496, avoid #
+        url = url.replace(/#.*/,"");
+        // For some reason, JSDS reports file URLs like "file:/" instead of "file:///", so they
+        // don't match up with the URLs we get back from the DOM
+        url = url.replace(/file:\/([^\/])/g, "file:///$1");
+        if (url.indexOf('chrome:')==0)
+        {
+            var m = reChromeCase.exec(url);  // 1 is package name, 2 is path
+            if (m)
+            {
+                url = "chrome://"+m[1].toLowerCase()+"/"+m[2];
+            }
+        }
+    }
+    return url;
+};
+
+this.denormalizeURL = function(url)
+{
+    return url.replace(/file:\/\/\//g, "file:/");
+};
+
+this.parseURLParams = function(url)
+{
+    var q = url ? url.indexOf("?") : -1;
+    if (q == -1)
+        return [];
+
+    var search = url.substr(q+1);
+    var h = search.lastIndexOf("#");
+    if (h != -1)
+        search = search.substr(0, h);
+
+    if (!search)
+        return [];
+
+    return this.parseURLEncodedText(search);
+};
+
+this.parseURLEncodedText = function(text)
+{
+    var maxValueLength = 25000;
+
+    var params = [];
+
+    // Unescape '+' characters that are used to encode a space.
+    // See section 2.2.in RFC 3986: http://www.ietf.org/rfc/rfc3986.txt
+    text = text.replace(/\+/g, " ");
+
+    var args = text.split("&");
+    for (var i = 0; i < args.length; ++i)
+    {
+        try {
+            var parts = args[i].split("=");
+            if (parts.length == 2)
+            {
+                if (parts[1].length > maxValueLength)
+                    parts[1] = this.$STR("LargeData");
+
+                params.push({name: decodeURIComponent(parts[0]), value: decodeURIComponent(parts[1])});
+            }
+            else
+                params.push({name: decodeURIComponent(parts[0]), value: ""});
+        }
+        catch (e)
+        {
+            if (FBTrace.DBG_ERRORS)
+            {
+                FBTrace.sysout("parseURLEncodedText EXCEPTION ", e);
+                FBTrace.sysout("parseURLEncodedText EXCEPTION URI", args[i]);
+            }
+        }
+    }
+
+    params.sort(function(a, b) { return a.name <= b.name ? -1 : 1; });
+
+    return params;
+};
+
+// TODO: xxxpedro lib. why loops in domplate are requiring array in parameters
+// as in response/request headers and get/post parameters in Net module?
+this.parseURLParamsArray = function(url)
+{
+    var q = url ? url.indexOf("?") : -1;
+    if (q == -1)
+        return [];
+
+    var search = url.substr(q+1);
+    var h = search.lastIndexOf("#");
+    if (h != -1)
+        search = search.substr(0, h);
+
+    if (!search)
+        return [];
+
+    return this.parseURLEncodedTextArray(search);
+};
+
+this.parseURLEncodedTextArray = function(text)
+{
+    var maxValueLength = 25000;
+
+    var params = [];
+
+    // Unescape '+' characters that are used to encode a space.
+    // See section 2.2.in RFC 3986: http://www.ietf.org/rfc/rfc3986.txt
+    text = text.replace(/\+/g, " ");
+
+    var args = text.split("&");
+    for (var i = 0; i < args.length; ++i)
+    {
+        try {
+            var parts = args[i].split("=");
+            if (parts.length == 2)
+            {
+                if (parts[1].length > maxValueLength)
+                    parts[1] = this.$STR("LargeData");
+
+                params.push({name: decodeURIComponent(parts[0]), value: [decodeURIComponent(parts[1])]});
+            }
+            else
+                params.push({name: decodeURIComponent(parts[0]), value: [""]});
+        }
+        catch (e)
+        {
+            if (FBTrace.DBG_ERRORS)
+            {
+                FBTrace.sysout("parseURLEncodedText EXCEPTION ", e);
+                FBTrace.sysout("parseURLEncodedText EXCEPTION URI", args[i]);
+            }
+        }
+    }
+
+    params.sort(function(a, b) { return a.name <= b.name ? -1 : 1; });
+
+    return params;
+};
+
+this.reEncodeURL = function(file, text)
+{
+    var lines = text.split("\n");
+    var params = this.parseURLEncodedText(lines[lines.length-1]);
+
+    var args = [];
+    for (var i = 0; i < params.length; ++i)
+        args.push(encodeURIComponent(params[i].name)+"="+encodeURIComponent(params[i].value));
+
+    var url = file.href;
+    url += (url.indexOf("?") == -1 ? "?" : "&") + args.join("&");
+
+    return url;
+};
+
+this.getResource = function(aURL)
+{
+    try
+    {
+        var channel=ioService.newChannel(aURL,null,null);
+        var input=channel.open();
+        return FBL.readFromStream(input);
+    }
+    catch (e)
+    {
+        if (FBTrace.DBG_ERRORS)
+            FBTrace.sysout("lib.getResource FAILS for "+aURL, e);
+    }
+};
+
+this.parseJSONString = function(jsonString, originURL)
+{
+    // See if this is a Prototype style *-secure request.
+    var regex = new RegExp(/^\/\*-secure-([\s\S]*)\*\/\s*$/);
+    var matches = regex.exec(jsonString);
+
+    if (matches)
+    {
+        jsonString = matches[1];
+
+        if (jsonString[0] == "\\" && jsonString[1] == "n")
+            jsonString = jsonString.substr(2);
+
+        if (jsonString[jsonString.length-2] == "\\" && jsonString[jsonString.length-1] == "n")
+            jsonString = jsonString.substr(0, jsonString.length-2);
+    }
+
+    if (jsonString.indexOf("&&&START&&&"))
+    {
+        regex = new RegExp(/&&&START&&& (.+) &&&END&&&/);
+        matches = regex.exec(jsonString);
+        if (matches)
+            jsonString = matches[1];
+    }
+
+    // throw on the extra parentheses
+    jsonString = "(" + jsonString + ")";
+
+    ///var s = Components.utils.Sandbox(originURL);
+    var jsonObject = null;
+
+    try
+    {
+        ///jsonObject = Components.utils.evalInSandbox(jsonString, s);
+
+        //jsonObject = Firebug.context.eval(jsonString);
+        jsonObject = Firebug.context.evaluate(jsonString, null, null, function(){return null;});
+    }
+    catch(e)
+    {
+        /***
+        if (e.message.indexOf("is not defined"))
+        {
+            var parts = e.message.split(" ");
+            s[parts[0]] = function(str){ return str; };
+            try {
+                jsonObject = Components.utils.evalInSandbox(jsonString, s);
+            } catch(ex) {
+                if (FBTrace.DBG_ERRORS || FBTrace.DBG_JSONVIEWER)
+                    FBTrace.sysout("jsonviewer.parseJSON EXCEPTION", e);
+                return null;
+            }
+        }
+        else
+        {/**/
+            if (FBTrace.DBG_ERRORS || FBTrace.DBG_JSONVIEWER)
+                FBTrace.sysout("jsonviewer.parseJSON EXCEPTION", e);
+            return null;
+        ///}
+    }
+
+    return jsonObject;
+};
+
+// ************************************************************************************************
+
+this.objectToString = function(object)
+{
+    try
+    {
+        return object+"";
+    }
+    catch (exc)
+    {
+        return null;
+    }
+};
+
+// ************************************************************************************************
+// Input Caret Position
+
+this.setSelectionRange = function(input, start, length)
+{
+    if (input.createTextRange)
+    {
+        var range = input.createTextRange();
+        range.moveStart("character", start);
+        range.moveEnd("character", length - input.value.length);
+        range.select();
+    }
+    else if (input.setSelectionRange)
+    {
+        input.setSelectionRange(start, length);
+        input.focus();
+    }
+};
+
+// ************************************************************************************************
+// Input Selection Start / Caret Position
+
+this.getInputSelectionStart = function(input)
+{
+    if (document.selection)
+    {
+        var range = input.ownerDocument.selection.createRange();
+        var text = range.text;
+
+        //console.log("range", range.text);
+
+        // if there is a selection, find the start position
+        if (text)
+        {
+            return input.value.indexOf(text);
+        }
+        // if there is no selection, find the caret position
+        else
+        {
+            range.moveStart("character", -input.value.length);
+
+            return range.text.length;
+        }
+    }
+    else if (typeof input.selectionStart != "undefined")
+        return input.selectionStart;
+
+    return 0;
+};
+
+// ************************************************************************************************
+// Opera Tab Fix
+
+function onOperaTabBlur(e)
+{
+    if (this.lastKey == 9)
+      this.focus();
+};
+
+function onOperaTabKeyDown(e)
+{
+    this.lastKey = e.keyCode;
+};
+
+function onOperaTabFocus(e)
+{
+    this.lastKey = null;
+};
+
+this.fixOperaTabKey = function(el)
+{
+    el.onfocus = onOperaTabFocus;
+    el.onblur = onOperaTabBlur;
+    el.onkeydown = onOperaTabKeyDown;
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.Property = function(object, name)
+{
+    this.object = object;
+    this.name = name;
+
+    this.getObject = function()
+    {
+        return object[name];
+    };
+};
+
+this.ErrorCopy = function(message)
+{
+    this.message = message;
+};
+
+function EventCopy(event)
+{
+    // Because event objects are destroyed arbitrarily by Gecko, we must make a copy of them to
+    // represent them long term in the inspector.
+    for (var name in event)
+    {
+        try {
+            this[name] = event[name];
+        } catch (exc) { }
+    }
+}
+
+this.EventCopy = EventCopy;
+
+
+// ************************************************************************************************
+// Type Checking
+
+var toString = Object.prototype.toString;
+var reFunction = /^\s*function(\s+[\w_$][\w\d_$]*)?\s*\(/;
+
+this.isArray = function(object) {
+    return toString.call(object) === '[object Array]';
+};
+
+this.isFunction = function(object) {
+    if (!object) return false;
+
+    try
+    {
+        // FIXME: xxxpedro this is failing in IE for the global "external" object
+        return toString.call(object) === "[object Function]" ||
+                this.isIE && typeof object != "string" && reFunction.test(""+object);
+    }
+    catch (E)
+    {
+        FBTrace.sysout("Lib.isFunction() failed for ", object);
+        return false;
+    }
+};
+
+
+// ************************************************************************************************
+// Instance Checking
+
+this.instanceOf = function(object, className)
+{
+    if (!object || typeof object != "object")
+        return false;
+
+    // Try to use the native instanceof operator. We can only use it when we know
+    // exactly the window where the object is located at
+    if (object.ownerDocument)
+    {
+        // find the correct window of the object
+        var win = object.ownerDocument.defaultView || object.ownerDocument.parentWindow;
+
+        // if the class is accessible in the window, uses the native instanceof operator
+        // if the instanceof evaluates to "true" we can assume it is a instance, but if it
+        // evaluates to "false" we must continue with the duck type detection below because
+        // the native object may be extended, thus breaking the instanceof result
+        // See Issue 3524: Firebug Lite Style Panel doesn't work if the native Element is extended
+        if (className in win && object instanceof win[className])
+            return true;
+    }
+    // If the object doesn't have the ownerDocument property, we'll try to look at
+    // the current context's window
+    else
+    {
+        // TODO: xxxpedro context
+        // Since we're not using yet a Firebug.context, we'll just use the top window
+        // (browser) as a reference
+        var win = Firebug.browser.window;
+        if (className in win)
+            return object instanceof win[className];
+    }
+
+    // get the duck type model from the cache
+    var cache = instanceCheckMap[className];
+    if (!cache)
+        return false;
+
+    // starts the hacky duck type detection
+    for(var n in cache)
+    {
+        var obj = cache[n];
+        var type = typeof obj;
+        obj = type == "object" ? obj : [obj];
+
+        for(var name in obj)
+        {
+            // avoid problems with extended native objects
+            // See Issue 3524: Firebug Lite Style Panel doesn't work if the native Element is extended
+            if (!obj.hasOwnProperty(name))
+                continue;
+
+            var value = obj[name];
+
+            if( n == "property" && !(value in object) ||
+                n == "method" && !this.isFunction(object[value]) ||
+                n == "value" && (""+object[name]).toLowerCase() != (""+value).toLowerCase() )
+                    return false;
+        }
+    }
+
+    return true;
+};
+
+var instanceCheckMap =
+{
+    // DuckTypeCheck:
+    // {
+    //     property: ["window", "document"],
+    //     method: "setTimeout",
+    //     value: {nodeType: 1}
+    // },
+
+    Window:
+    {
+        property: ["window", "document"],
+        method: "setTimeout"
+    },
+
+    Document:
+    {
+        property: ["body", "cookie"],
+        method: "getElementById"
+    },
+
+    Node:
+    {
+        property: "ownerDocument",
+        method: "appendChild"
+    },
+
+    Element:
+    {
+        property: "tagName",
+        value: {nodeType: 1}
+    },
+
+    Location:
+    {
+        property: ["hostname", "protocol"],
+        method: "assign"
+    },
+
+    HTMLImageElement:
+    {
+        property: "useMap",
+        value:
+        {
+            nodeType: 1,
+            tagName: "img"
+        }
+    },
+
+    HTMLAnchorElement:
+    {
+        property: "hreflang",
+        value:
+        {
+            nodeType: 1,
+            tagName: "a"
+        }
+    },
+
+    HTMLInputElement:
+    {
+        property: "form",
+        value:
+        {
+            nodeType: 1,
+            tagName: "input"
+        }
+    },
+
+    HTMLButtonElement:
+    {
+        // ?
+    },
+
+    HTMLFormElement:
+    {
+        method: "submit",
+        value:
+        {
+            nodeType: 1,
+            tagName: "form"
+        }
+    },
+
+    HTMLBodyElement:
+    {
+
+    },
+
+    HTMLHtmlElement:
+    {
+
+    },
+
+    CSSStyleRule:
+    {
+        property: ["selectorText", "style"]
+    }
+
+};
+
+
+// ************************************************************************************************
+// DOM Constants
+
+/*
+
+Problems:
+
+  - IE does not have window.Node, window.Element, etc
+  - for (var name in Node.prototype) return nothing on FF
+
+*/
+
+
+var domMemberMap2 = {};
+
+var domMemberMap2Sandbox = null;
+
+var getDomMemberMap2 = function(name)
+{
+    if (!domMemberMap2Sandbox)
+    {
+        var doc = Firebug.chrome.document;
+        var frame = doc.createElement("iframe");
+
+        frame.id = "FirebugSandbox";
+        frame.style.display = "none";
+        frame.src = "about:blank";
+
+        doc.body.appendChild(frame);
+
+        domMemberMap2Sandbox = frame.window || frame.contentWindow;
+    }
+
+    var props = [];
+
+    //var object = domMemberMap2Sandbox[name];
+    //object = object.prototype || object;
+
+    var object = null;
+
+    if (name == "Window")
+        object = domMemberMap2Sandbox.window;
+
+    else if (name == "Document")
+        object = domMemberMap2Sandbox.document;
+
+    else if (name == "HTMLScriptElement")
+        object = domMemberMap2Sandbox.document.createElement("script");
+
+    else if (name == "HTMLAnchorElement")
+        object = domMemberMap2Sandbox.document.createElement("a");
+
+    else if (name.indexOf("Element") != -1)
+    {
+        object = domMemberMap2Sandbox.document.createElement("div");
+    }
+
+    if (object)
+    {
+        //object = object.prototype || object;
+
+        //props  = 'addEventListener,document,location,navigator,window'.split(',');
+
+        for (var n in object)
+          props.push(n);
+    }
+    /**/
+
+    return props;
+    return extendArray(props, domMemberMap[name]);
+};
+
+// xxxpedro experimental get DOM members
+this.getDOMMembers = function(object)
+{
+    if (!domMemberCache)
+    {
+        FBL.domMemberCache = domMemberCache = {};
+
+        for (var name in domMemberMap)
+        {
+            var builtins = getDomMemberMap2(name);
+            var cache = domMemberCache[name] = {};
+
+            /*
+            if (name.indexOf("Element") != -1)
+            {
+                this.append(cache, this.getDOMMembers("Node"));
+                this.append(cache, this.getDOMMembers("Element"));
+            }
+            /**/
+
+            for (var i = 0; i < builtins.length; ++i)
+                cache[builtins[i]] = i;
+        }
+    }
+
+    try
+    {
+        if (this.instanceOf(object, "Window"))
+            { return domMemberCache.Window; }
+        else if (this.instanceOf(object, "Document") || this.instanceOf(object, "XMLDocument"))
+            { return domMemberCache.Document; }
+        else if (this.instanceOf(object, "Location"))
+            { return domMemberCache.Location; }
+        else if (this.instanceOf(object, "HTMLImageElement"))
+            { return domMemberCache.HTMLImageElement; }
+        else if (this.instanceOf(object, "HTMLAnchorElement"))
+            { return domMemberCache.HTMLAnchorElement; }
+        else if (this.instanceOf(object, "HTMLInputElement"))
+            { return domMemberCache.HTMLInputElement; }
+        else if (this.instanceOf(object, "HTMLButtonElement"))
+            { return domMemberCache.HTMLButtonElement; }
+        else if (this.instanceOf(object, "HTMLFormElement"))
+            { return domMemberCache.HTMLFormElement; }
+        else if (this.instanceOf(object, "HTMLBodyElement"))
+            { return domMemberCache.HTMLBodyElement; }
+        else if (this.instanceOf(object, "HTMLHtmlElement"))
+            { return domMemberCache.HTMLHtmlElement; }
+        else if (this.instanceOf(object, "HTMLScriptElement"))
+            { return domMemberCache.HTMLScriptElement; }
+        else if (this.instanceOf(object, "HTMLTableElement"))
+            { return domMemberCache.HTMLTableElement; }
+        else if (this.instanceOf(object, "HTMLTableRowElement"))
+            { return domMemberCache.HTMLTableRowElement; }
+        else if (this.instanceOf(object, "HTMLTableCellElement"))
+            { return domMemberCache.HTMLTableCellElement; }
+        else if (this.instanceOf(object, "HTMLIFrameElement"))
+            { return domMemberCache.HTMLIFrameElement; }
+        else if (this.instanceOf(object, "SVGSVGElement"))
+            { return domMemberCache.SVGSVGElement; }
+        else if (this.instanceOf(object, "SVGElement"))
+            { return domMemberCache.SVGElement; }
+        else if (this.instanceOf(object, "Element"))
+            { return domMemberCache.Element; }
+        else if (this.instanceOf(object, "Text") || this.instanceOf(object, "CDATASection"))
+            { return domMemberCache.Text; }
+        else if (this.instanceOf(object, "Attr"))
+            { return domMemberCache.Attr; }
+        else if (this.instanceOf(object, "Node"))
+            { return domMemberCache.Node; }
+        else if (this.instanceOf(object, "Event") || this.instanceOf(object, "EventCopy"))
+            { return domMemberCache.Event; }
+        else
+            return {};
+    }
+    catch(E)
+    {
+        if (FBTrace.DBG_ERRORS)
+            FBTrace.sysout("lib.getDOMMembers FAILED ", E);
+
+        return {};
+    }
+};
+
+
+/*
+this.getDOMMembers = function(object)
+{
+    if (!domMemberCache)
+    {
+        domMemberCache = {};
+
+        for (var name in domMemberMap)
+        {
+            var builtins = domMemberMap[name];
+            var cache = domMemberCache[name] = {};
+
+            for (var i = 0; i < builtins.length; ++i)
+                cache[builtins[i]] = i;
+        }
+    }
+
+    try
+    {
+        if (this.instanceOf(object, "Window"))
+            { return domMemberCache.Window; }
+        else if (object instanceof Document || object instanceof XMLDocument)
+            { return domMemberCache.Document; }
+        else if (object instanceof Location)
+            { return domMemberCache.Location; }
+        else if (object instanceof HTMLImageElement)
+            { return domMemberCache.HTMLImageElement; }
+        else if (object instanceof HTMLAnchorElement)
+            { return domMemberCache.HTMLAnchorElement; }
+        else if (object instanceof HTMLInputElement)
+            { return domMemberCache.HTMLInputElement; }
+        else if (object instanceof HTMLButtonElement)
+            { return domMemberCache.HTMLButtonElement; }
+        else if (object instanceof HTMLFormElement)
+            { return domMemberCache.HTMLFormElement; }
+        else if (object instanceof HTMLBodyElement)
+            { return domMemberCache.HTMLBodyElement; }
+        else if (object instanceof HTMLHtmlElement)
+            { return domMemberCache.HTMLHtmlElement; }
+        else if (object instanceof HTMLScriptElement)
+            { return domMemberCache.HTMLScriptElement; }
+        else if (object instanceof HTMLTableElement)
+            { return domMemberCache.HTMLTableElement; }
+        else if (object instanceof HTMLTableRowElement)
+            { return domMemberCache.HTMLTableRowElement; }
+        else if (object instanceof HTMLTableCellElement)
+            { return domMemberCache.HTMLTableCellElement; }
+        else if (object instanceof HTMLIFrameElement)
+            { return domMemberCache.HTMLIFrameElement; }
+        else if (object instanceof SVGSVGElement)
+            { return domMemberCache.SVGSVGElement; }
+        else if (object instanceof SVGElement)
+            { return domMemberCache.SVGElement; }
+        else if (object instanceof Element)
+            { return domMemberCache.Element; }
+        else if (object instanceof Text || object instanceof CDATASection)
+            { return domMemberCache.Text; }
+        else if (object instanceof Attr)
+            { return domMemberCache.Attr; }
+        else if (object instanceof Node)
+            { return domMemberCache.Node; }
+        else if (object instanceof Event || object instanceof EventCopy)
+            { return domMemberCache.Event; }
+        else
+            return {};
+    }
+    catch(E)
+    {
+        return {};
+    }
+};
+/**/
+
+this.isDOMMember = function(object, propName)
+{
+    var members = this.getDOMMembers(object);
+    return members && propName in members;
+};
+
+var domMemberCache = null;
+var domMemberMap = {};
+
+domMemberMap.Window =
+[
+    "document",
+    "frameElement",
+
+    "innerWidth",
+    "innerHeight",
+    "outerWidth",
+    "outerHeight",
+    "screenX",
+    "screenY",
+    "pageXOffset",
+    "pageYOffset",
+    "scrollX",
+    "scrollY",
+    "scrollMaxX",
+    "scrollMaxY",
+
+    "status",
+    "defaultStatus",
+
+    "parent",
+    "opener",
+    "top",
+    "window",
+    "content",
+    "self",
+
+    "location",
+    "history",
+    "frames",
+    "navigator",
+    "screen",
+    "menubar",
+    "toolbar",
+    "locationbar",
+    "personalbar",
+    "statusbar",
+    "directories",
+    "scrollbars",
+    "fullScreen",
+    "netscape",
+    "java",
+    "console",
+    "Components",
+    "controllers",
+    "closed",
+    "crypto",
+    "pkcs11",
+
+    "name",
+    "property",
+    "length",
+
+    "sessionStorage",
+    "globalStorage",
+
+    "setTimeout",
+    "setInterval",
+    "clearTimeout",
+    "clearInterval",
+    "addEventListener",
+    "removeEventListener",
+    "dispatchEvent",
+    "getComputedStyle",
+    "captureEvents",
+    "releaseEvents",
+    "routeEvent",
+    "enableExternalCapture",
+    "disableExternalCapture",
+    "moveTo",
+    "moveBy",
+    "resizeTo",
+    "resizeBy",
+    "scroll",
+    "scrollTo",
+    "scrollBy",
+    "scrollByLines",
+    "scrollByPages",
+    "sizeToContent",
+    "setResizable",
+    "getSelection",
+    "open",
+    "openDialog",
+    "close",
+    "alert",
+    "confirm",
+    "prompt",
+    "dump",
+    "focus",
+    "blur",
+    "find",
+    "back",
+    "forward",
+    "home",
+    "stop",
+    "print",
+    "atob",
+    "btoa",
+    "updateCommands",
+    "XPCNativeWrapper",
+    "GeckoActiveXObject",
+    "applicationCache"      // FF3
+];
+
+domMemberMap.Location =
+[
+    "href",
+    "protocol",
+    "host",
+    "hostname",
+    "port",
+    "pathname",
+    "search",
+    "hash",
+
+    "assign",
+    "reload",
+    "replace"
+];
+
+domMemberMap.Node =
+[
+    "id",
+    "className",
+
+    "nodeType",
+    "tagName",
+    "nodeName",
+    "localName",
+    "prefix",
+    "namespaceURI",
+    "nodeValue",
+
+    "ownerDocument",
+    "parentNode",
+    "offsetParent",
+    "nextSibling",
+    "previousSibling",
+    "firstChild",
+    "lastChild",
+    "childNodes",
+    "attributes",
+
+    "dir",
+    "baseURI",
+    "textContent",
+    "innerHTML",
+
+    "addEventListener",
+    "removeEventListener",
+    "dispatchEvent",
+    "cloneNode",
+    "appendChild",
+    "insertBefore",
+    "replaceChild",
+    "removeChild",
+    "compareDocumentPosition",
+    "hasAttributes",
+    "hasChildNodes",
+    "lookupNamespaceURI",
+    "lookupPrefix",
+    "normalize",
+    "isDefaultNamespace",
+    "isEqualNode",
+    "isSameNode",
+    "isSupported",
+    "getFeature",
+    "getUserData",
+    "setUserData"
+];
+
+domMemberMap.Document = extendArray(domMemberMap.Node,
+[
+    "documentElement",
+    "body",
+    "title",
+    "location",
+    "referrer",
+    "cookie",
+    "contentType",
+    "lastModified",
+    "characterSet",
+    "inputEncoding",
+    "xmlEncoding",
+    "xmlStandalone",
+    "xmlVersion",
+    "strictErrorChecking",
+    "documentURI",
+    "URL",
+
+    "defaultView",
+    "doctype",
+    "implementation",
+    "styleSheets",
+    "images",
+    "links",
+    "forms",
+    "anchors",
+    "embeds",
+    "plugins",
+    "applets",
+
+    "width",
+    "height",
+
+    "designMode",
+    "compatMode",
+    "async",
+    "preferredStylesheetSet",
+
+    "alinkColor",
+    "linkColor",
+    "vlinkColor",
+    "bgColor",
+    "fgColor",
+    "domain",
+
+    "addEventListener",
+    "removeEventListener",
+    "dispatchEvent",
+    "captureEvents",
+    "releaseEvents",
+    "routeEvent",
+    "clear",
+    "open",
+    "close",
+    "execCommand",
+    "execCommandShowHelp",
+    "getElementsByName",
+    "getSelection",
+    "queryCommandEnabled",
+    "queryCommandIndeterm",
+    "queryCommandState",
+    "queryCommandSupported",
+    "queryCommandText",
+    "queryCommandValue",
+    "write",
+    "writeln",
+    "adoptNode",
+    "appendChild",
+    "removeChild",
+    "renameNode",
+    "cloneNode",
+    "compareDocumentPosition",
+    "createAttribute",
+    "createAttributeNS",
+    "createCDATASection",
+    "createComment",
+    "createDocumentFragment",
+    "createElement",
+    "createElementNS",
+    "createEntityReference",
+    "createEvent",
+    "createExpression",
+    "createNSResolver",
+    "createNodeIterator",
+    "createProcessingInstruction",
+    "createRange",
+    "createTextNode",
+    "createTreeWalker",
+    "domConfig",
+    "evaluate",
+    "evaluateFIXptr",
+    "evaluateXPointer",
+    "getAnonymousElementByAttribute",
+    "getAnonymousNodes",
+    "addBinding",
+    "removeBinding",
+    "getBindingParent",
+    "getBoxObjectFor",
+    "setBoxObjectFor",
+    "getElementById",
+    "getElementsByTagName",
+    "getElementsByTagNameNS",
+    "hasAttributes",
+    "hasChildNodes",
+    "importNode",
+    "insertBefore",
+    "isDefaultNamespace",
+    "isEqualNode",
+    "isSameNode",
+    "isSupported",
+    "load",
+    "loadBindingDocument",
+    "lookupNamespaceURI",
+    "lookupPrefix",
+    "normalize",
+    "normalizeDocument",
+    "getFeature",
+    "getUserData",
+    "setUserData"
+]);
+
+domMemberMap.Element = extendArray(domMemberMap.Node,
+[
+    "clientWidth",
+    "clientHeight",
+    "offsetLeft",
+    "offsetTop",
+    "offsetWidth",
+    "offsetHeight",
+    "scrollLeft",
+    "scrollTop",
+    "scrollWidth",
+    "scrollHeight",
+
+    "style",
+
+    "tabIndex",
+    "title",
+    "lang",
+    "align",
+    "spellcheck",
+
+    "addEventListener",
+    "removeEventListener",
+    "dispatchEvent",
+    "focus",
+    "blur",
+    "cloneNode",
+    "appendChild",
+    "insertBefore",
+    "replaceChild",
+    "removeChild",
+    "compareDocumentPosition",
+    "getElementsByTagName",
+    "getElementsByTagNameNS",
+    "getAttribute",
+    "getAttributeNS",
+    "getAttributeNode",
+    "getAttributeNodeNS",
+    "setAttribute",
+    "setAttributeNS",
+    "setAttributeNode",
+    "setAttributeNodeNS",
+    "removeAttribute",
+    "removeAttributeNS",
+    "removeAttributeNode",
+    "hasAttribute",
+    "hasAttributeNS",
+    "hasAttributes",
+    "hasChildNodes",
+    "lookupNamespaceURI",
+    "lookupPrefix",
+    "normalize",
+    "isDefaultNamespace",
+    "isEqualNode",
+    "isSameNode",
+    "isSupported",
+    "getFeature",
+    "getUserData",
+    "setUserData"
+]);
+
+domMemberMap.SVGElement = extendArray(domMemberMap.Element,
+[
+    "x",
+    "y",
+    "width",
+    "height",
+    "rx",
+    "ry",
+    "transform",
+    "href",
+
+    "ownerSVGElement",
+    "viewportElement",
+    "farthestViewportElement",
+    "nearestViewportElement",
+
+    "getBBox",
+    "getCTM",
+    "getScreenCTM",
+    "getTransformToElement",
+    "getPresentationAttribute",
+    "preserveAspectRatio"
+]);
+
+domMemberMap.SVGSVGElement = extendArray(domMemberMap.Element,
+[
+    "x",
+    "y",
+    "width",
+    "height",
+    "rx",
+    "ry",
+    "transform",
+
+    "viewBox",
+    "viewport",
+    "currentView",
+    "useCurrentView",
+    "pixelUnitToMillimeterX",
+    "pixelUnitToMillimeterY",
+    "screenPixelToMillimeterX",
+    "screenPixelToMillimeterY",
+    "currentScale",
+    "currentTranslate",
+    "zoomAndPan",
+
+    "ownerSVGElement",
+    "viewportElement",
+    "farthestViewportElement",
+    "nearestViewportElement",
+    "contentScriptType",
+    "contentStyleType",
+
+    "getBBox",
+    "getCTM",
+    "getScreenCTM",
+    "getTransformToElement",
+    "getEnclosureList",
+    "getIntersectionList",
+    "getViewboxToViewportTransform",
+    "getPresentationAttribute",
+    "getElementById",
+    "checkEnclosure",
+    "checkIntersection",
+    "createSVGAngle",
+    "createSVGLength",
+    "createSVGMatrix",
+    "createSVGNumber",
+    "createSVGPoint",
+    "createSVGRect",
+    "createSVGString",
+    "createSVGTransform",
+    "createSVGTransformFromMatrix",
+    "deSelectAll",
+    "preserveAspectRatio",
+    "forceRedraw",
+    "suspendRedraw",
+    "unsuspendRedraw",
+    "unsuspendRedrawAll",
+    "getCurrentTime",
+    "setCurrentTime",
+    "animationsPaused",
+    "pauseAnimations",
+    "unpauseAnimations"
+]);
+
+domMemberMap.HTMLImageElement = extendArray(domMemberMap.Element,
+[
+    "src",
+    "naturalWidth",
+    "naturalHeight",
+    "width",
+    "height",
+    "x",
+    "y",
+    "name",
+    "alt",
+    "longDesc",
+    "lowsrc",
+    "border",
+    "complete",
+    "hspace",
+    "vspace",
+    "isMap",
+    "useMap"
+]);
+
+domMemberMap.HTMLAnchorElement = extendArray(domMemberMap.Element,
+[
+    "name",
+    "target",
+    "accessKey",
+    "href",
+    "protocol",
+    "host",
+    "hostname",
+    "port",
+    "pathname",
+    "search",
+    "hash",
+    "hreflang",
+    "coords",
+    "shape",
+    "text",
+    "type",
+    "rel",
+    "rev",
+    "charset"
+]);
+
+domMemberMap.HTMLIFrameElement = extendArray(domMemberMap.Element,
+[
+    "contentDocument",
+    "contentWindow",
+    "frameBorder",
+    "height",
+    "longDesc",
+    "marginHeight",
+    "marginWidth",
+    "name",
+    "scrolling",
+    "src",
+    "width"
+]);
+
+domMemberMap.HTMLTableElement = extendArray(domMemberMap.Element,
+[
+    "bgColor",
+    "border",
+    "caption",
+    "cellPadding",
+    "cellSpacing",
+    "frame",
+    "rows",
+    "rules",
+    "summary",
+    "tBodies",
+    "tFoot",
+    "tHead",
+    "width",
+
+    "createCaption",
+    "createTFoot",
+    "createTHead",
+    "deleteCaption",
+    "deleteRow",
+    "deleteTFoot",
+    "deleteTHead",
+    "insertRow"
+]);
+
+domMemberMap.HTMLTableRowElement = extendArray(domMemberMap.Element,
+[
+    "bgColor",
+    "cells",
+    "ch",
+    "chOff",
+    "rowIndex",
+    "sectionRowIndex",
+    "vAlign",
+
+    "deleteCell",
+    "insertCell"
+]);
+
+domMemberMap.HTMLTableCellElement = extendArray(domMemberMap.Element,
+[
+    "abbr",
+    "axis",
+    "bgColor",
+    "cellIndex",
+    "ch",
+    "chOff",
+    "colSpan",
+    "headers",
+    "height",
+    "noWrap",
+    "rowSpan",
+    "scope",
+    "vAlign",
+    "width"
+
+]);
+
+domMemberMap.HTMLScriptElement = extendArray(domMemberMap.Element,
+[
+    "src"
+]);
+
+domMemberMap.HTMLButtonElement = extendArray(domMemberMap.Element,
+[
+    "accessKey",
+    "disabled",
+    "form",
+    "name",
+    "type",
+    "value",
+
+    "click"
+]);
+
+domMemberMap.HTMLInputElement = extendArray(domMemberMap.Element,
+[
+    "type",
+    "value",
+    "checked",
+    "accept",
+    "accessKey",
+    "alt",
+    "controllers",
+    "defaultChecked",
+    "defaultValue",
+    "disabled",
+    "form",
+    "maxLength",
+    "name",
+    "readOnly",
+    "selectionEnd",
+    "selectionStart",
+    "size",
+    "src",
+    "textLength",
+    "useMap",
+
+    "click",
+    "select",
+    "setSelectionRange"
+]);
+
+domMemberMap.HTMLFormElement = extendArray(domMemberMap.Element,
+[
+    "acceptCharset",
+    "action",
+    "author",
+    "elements",
+    "encoding",
+    "enctype",
+    "entry_id",
+    "length",
+    "method",
+    "name",
+    "post",
+    "target",
+    "text",
+    "url",
+
+    "reset",
+    "submit"
+]);
+
+domMemberMap.HTMLBodyElement = extendArray(domMemberMap.Element,
+[
+    "aLink",
+    "background",
+    "bgColor",
+    "link",
+    "text",
+    "vLink"
+]);
+
+domMemberMap.HTMLHtmlElement = extendArray(domMemberMap.Element,
+[
+    "version"
+]);
+
+domMemberMap.Text = extendArray(domMemberMap.Node,
+[
+    "data",
+    "length",
+
+    "appendData",
+    "deleteData",
+    "insertData",
+    "replaceData",
+    "splitText",
+    "substringData"
+]);
+
+domMemberMap.Attr = extendArray(domMemberMap.Node,
+[
+    "name",
+    "value",
+    "specified",
+    "ownerElement"
+]);
+
+domMemberMap.Event =
+[
+    "type",
+    "target",
+    "currentTarget",
+    "originalTarget",
+    "explicitOriginalTarget",
+    "relatedTarget",
+    "rangeParent",
+    "rangeOffset",
+    "view",
+
+    "keyCode",
+    "charCode",
+    "screenX",
+    "screenY",
+    "clientX",
+    "clientY",
+    "layerX",
+    "layerY",
+    "pageX",
+    "pageY",
+
+    "detail",
+    "button",
+    "which",
+    "ctrlKey",
+    "shiftKey",
+    "altKey",
+    "metaKey",
+
+    "eventPhase",
+    "timeStamp",
+    "bubbles",
+    "cancelable",
+    "cancelBubble",
+
+    "isTrusted",
+    "isChar",
+
+    "getPreventDefault",
+    "initEvent",
+    "initMouseEvent",
+    "initKeyEvent",
+    "initUIEvent",
+    "preventBubble",
+    "preventCapture",
+    "preventDefault",
+    "stopPropagation"
+];
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.domConstantMap =
+{
+    "ELEMENT_NODE": 1,
+    "ATTRIBUTE_NODE": 1,
+    "TEXT_NODE": 1,
+    "CDATA_SECTION_NODE": 1,
+    "ENTITY_REFERENCE_NODE": 1,
+    "ENTITY_NODE": 1,
+    "PROCESSING_INSTRUCTION_NODE": 1,
+    "COMMENT_NODE": 1,
+    "DOCUMENT_NODE": 1,
+    "DOCUMENT_TYPE_NODE": 1,
+    "DOCUMENT_FRAGMENT_NODE": 1,
+    "NOTATION_NODE": 1,
+
+    "DOCUMENT_POSITION_DISCONNECTED": 1,
+    "DOCUMENT_POSITION_PRECEDING": 1,
+    "DOCUMENT_POSITION_FOLLOWING": 1,
+    "DOCUMENT_POSITION_CONTAINS": 1,
+    "DOCUMENT_POSITION_CONTAINED_BY": 1,
+    "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC": 1,
+
+    "UNKNOWN_RULE": 1,
+    "STYLE_RULE": 1,
+    "CHARSET_RULE": 1,
+    "IMPORT_RULE": 1,
+    "MEDIA_RULE": 1,
+    "FONT_FACE_RULE": 1,
+    "PAGE_RULE": 1,
+
+    "CAPTURING_PHASE": 1,
+    "AT_TARGET": 1,
+    "BUBBLING_PHASE": 1,
+
+    "SCROLL_PAGE_UP": 1,
+    "SCROLL_PAGE_DOWN": 1,
+
+    "MOUSEUP": 1,
+    "MOUSEDOWN": 1,
+    "MOUSEOVER": 1,
+    "MOUSEOUT": 1,
+    "MOUSEMOVE": 1,
+    "MOUSEDRAG": 1,
+    "CLICK": 1,
+    "DBLCLICK": 1,
+    "KEYDOWN": 1,
+    "KEYUP": 1,
+    "KEYPRESS": 1,
+    "DRAGDROP": 1,
+    "FOCUS": 1,
+    "BLUR": 1,
+    "SELECT": 1,
+    "CHANGE": 1,
+    "RESET": 1,
+    "SUBMIT": 1,
+    "SCROLL": 1,
+    "LOAD": 1,
+    "UNLOAD": 1,
+    "XFER_DONE": 1,
+    "ABORT": 1,
+    "ERROR": 1,
+    "LOCATE": 1,
+    "MOVE": 1,
+    "RESIZE": 1,
+    "FORWARD": 1,
+    "HELP": 1,
+    "BACK": 1,
+    "TEXT": 1,
+
+    "ALT_MASK": 1,
+    "CONTROL_MASK": 1,
+    "SHIFT_MASK": 1,
+    "META_MASK": 1,
+
+    "DOM_VK_TAB": 1,
+    "DOM_VK_PAGE_UP": 1,
+    "DOM_VK_PAGE_DOWN": 1,
+    "DOM_VK_UP": 1,
+    "DOM_VK_DOWN": 1,
+    "DOM_VK_LEFT": 1,
+    "DOM_VK_RIGHT": 1,
+    "DOM_VK_CANCEL": 1,
+    "DOM_VK_HELP": 1,
+    "DOM_VK_BACK_SPACE": 1,
+    "DOM_VK_CLEAR": 1,
+    "DOM_VK_RETURN": 1,
+    "DOM_VK_ENTER": 1,
+    "DOM_VK_SHIFT": 1,
+    "DOM_VK_CONTROL": 1,
+    "DOM_VK_ALT": 1,
+    "DOM_VK_PAUSE": 1,
+    "DOM_VK_CAPS_LOCK": 1,
+    "DOM_VK_ESCAPE": 1,
+    "DOM_VK_SPACE": 1,
+    "DOM_VK_END": 1,
+    "DOM_VK_HOME": 1,
+    "DOM_VK_PRINTSCREEN": 1,
+    "DOM_VK_INSERT": 1,
+    "DOM_VK_DELETE": 1,
+    "DOM_VK_0": 1,
+    "DOM_VK_1": 1,
+    "DOM_VK_2": 1,
+    "DOM_VK_3": 1,
+    "DOM_VK_4": 1,
+    "DOM_VK_5": 1,
+    "DOM_VK_6": 1,
+    "DOM_VK_7": 1,
+    "DOM_VK_8": 1,
+    "DOM_VK_9": 1,
+    "DOM_VK_SEMICOLON": 1,
+    "DOM_VK_EQUALS": 1,
+    "DOM_VK_A": 1,
+    "DOM_VK_B": 1,
+    "DOM_VK_C": 1,
+    "DOM_VK_D": 1,
+    "DOM_VK_E": 1,
+    "DOM_VK_F": 1,
+    "DOM_VK_G": 1,
+    "DOM_VK_H": 1,
+    "DOM_VK_I": 1,
+    "DOM_VK_J": 1,
+    "DOM_VK_K": 1,
+    "DOM_VK_L": 1,
+    "DOM_VK_M": 1,
+    "DOM_VK_N": 1,
+    "DOM_VK_O": 1,
+    "DOM_VK_P": 1,
+    "DOM_VK_Q": 1,
+    "DOM_VK_R": 1,
+    "DOM_VK_S": 1,
+    "DOM_VK_T": 1,
+    "DOM_VK_U": 1,
+    "DOM_VK_V": 1,
+    "DOM_VK_W": 1,
+    "DOM_VK_X": 1,
+    "DOM_VK_Y": 1,
+    "DOM_VK_Z": 1,
+    "DOM_VK_CONTEXT_MENU": 1,
+    "DOM_VK_NUMPAD0": 1,
+    "DOM_VK_NUMPAD1": 1,
+    "DOM_VK_NUMPAD2": 1,
+    "DOM_VK_NUMPAD3": 1,
+    "DOM_VK_NUMPAD4": 1,
+    "DOM_VK_NUMPAD5": 1,
+    "DOM_VK_NUMPAD6": 1,
+    "DOM_VK_NUMPAD7": 1,
+    "DOM_VK_NUMPAD8": 1,
+    "DOM_VK_NUMPAD9": 1,
+    "DOM_VK_MULTIPLY": 1,
+    "DOM_VK_ADD": 1,
+    "DOM_VK_SEPARATOR": 1,
+    "DOM_VK_SUBTRACT": 1,
+    "DOM_VK_DECIMAL": 1,
+    "DOM_VK_DIVIDE": 1,
+    "DOM_VK_F1": 1,
+    "DOM_VK_F2": 1,
+    "DOM_VK_F3": 1,
+    "DOM_VK_F4": 1,
+    "DOM_VK_F5": 1,
+    "DOM_VK_F6": 1,
+    "DOM_VK_F7": 1,
+    "DOM_VK_F8": 1,
+    "DOM_VK_F9": 1,
+    "DOM_VK_F10": 1,
+    "DOM_VK_F11": 1,
+    "DOM_VK_F12": 1,
+    "DOM_VK_F13": 1,
+    "DOM_VK_F14": 1,
+    "DOM_VK_F15": 1,
+    "DOM_VK_F16": 1,
+    "DOM_VK_F17": 1,
+    "DOM_VK_F18": 1,
+    "DOM_VK_F19": 1,
+    "DOM_VK_F20": 1,
+    "DOM_VK_F21": 1,
+    "DOM_VK_F22": 1,
+    "DOM_VK_F23": 1,
+    "DOM_VK_F24": 1,
+    "DOM_VK_NUM_LOCK": 1,
+    "DOM_VK_SCROLL_LOCK": 1,
+    "DOM_VK_COMMA": 1,
+    "DOM_VK_PERIOD": 1,
+    "DOM_VK_SLASH": 1,
+    "DOM_VK_BACK_QUOTE": 1,
+    "DOM_VK_OPEN_BRACKET": 1,
+    "DOM_VK_BACK_SLASH": 1,
+    "DOM_VK_CLOSE_BRACKET": 1,
+    "DOM_VK_QUOTE": 1,
+    "DOM_VK_META": 1,
+
+    "SVG_ZOOMANDPAN_DISABLE": 1,
+    "SVG_ZOOMANDPAN_MAGNIFY": 1,
+    "SVG_ZOOMANDPAN_UNKNOWN": 1
+};
+
+this.cssInfo =
+{
+    "background": ["bgRepeat", "bgAttachment", "bgPosition", "color", "systemColor", "none"],
+    "background-attachment": ["bgAttachment"],
+    "background-color": ["color", "systemColor"],
+    "background-image": ["none"],
+    "background-position": ["bgPosition"],
+    "background-repeat": ["bgRepeat"],
+
+    "border": ["borderStyle", "thickness", "color", "systemColor", "none"],
+    "border-top": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
+    "border-right": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
+    "border-bottom": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
+    "border-left": ["borderStyle", "borderCollapse", "color", "systemColor", "none"],
+    "border-collapse": ["borderCollapse"],
+    "border-color": ["color", "systemColor"],
+    "border-top-color": ["color", "systemColor"],
+    "border-right-color": ["color", "systemColor"],
+    "border-bottom-color": ["color", "systemColor"],
+    "border-left-color": ["color", "systemColor"],
+    "border-spacing": [],
+    "border-style": ["borderStyle"],
+    "border-top-style": ["borderStyle"],
+    "border-right-style": ["borderStyle"],
+    "border-bottom-style": ["borderStyle"],
+    "border-left-style": ["borderStyle"],
+    "border-width": ["thickness"],
+    "border-top-width": ["thickness"],
+    "border-right-width": ["thickness"],
+    "border-bottom-width": ["thickness"],
+    "border-left-width": ["thickness"],
+
+    "bottom": ["auto"],
+    "caption-side": ["captionSide"],
+    "clear": ["clear", "none"],
+    "clip": ["auto"],
+    "color": ["color", "systemColor"],
+    "content": ["content"],
+    "counter-increment": ["none"],
+    "counter-reset": ["none"],
+    "cursor": ["cursor", "none"],
+    "direction": ["direction"],
+    "display": ["display", "none"],
+    "empty-cells": [],
+    "float": ["float", "none"],
+    "font": ["fontStyle", "fontVariant", "fontWeight", "fontFamily"],
+
+    "font-family": ["fontFamily"],
+    "font-size": ["fontSize"],
+    "font-size-adjust": [],
+    "font-stretch": [],
+    "font-style": ["fontStyle"],
+    "font-variant": ["fontVariant"],
+    "font-weight": ["fontWeight"],
+
+    "height": ["auto"],
+    "left": ["auto"],
+    "letter-spacing": [],
+    "line-height": [],
+
+    "list-style": ["listStyleType", "listStylePosition", "none"],
+    "list-style-image": ["none"],
+    "list-style-position": ["listStylePosition"],
+    "list-style-type": ["listStyleType", "none"],
+
+    "margin": [],
+    "margin-top": [],
+    "margin-right": [],
+    "margin-bottom": [],
+    "margin-left": [],
+
+    "marker-offset": ["auto"],
+    "min-height": ["none"],
+    "max-height": ["none"],
+    "min-width": ["none"],
+    "max-width": ["none"],
+
+    "outline": ["borderStyle", "color", "systemColor", "none"],
+    "outline-color": ["color", "systemColor"],
+    "outline-style": ["borderStyle"],
+    "outline-width": [],
+
+    "overflow": ["overflow", "auto"],
+    "overflow-x": ["overflow", "auto"],
+    "overflow-y": ["overflow", "auto"],
+
+    "padding": [],
+    "padding-top": [],
+    "padding-right": [],
+    "padding-bottom": [],
+    "padding-left": [],
+
+    "position": ["position"],
+    "quotes": ["none"],
+    "right": ["auto"],
+    "table-layout": ["tableLayout", "auto"],
+    "text-align": ["textAlign"],
+    "text-decoration": ["textDecoration", "none"],
+    "text-indent": [],
+    "text-shadow": [],
+    "text-transform": ["textTransform", "none"],
+    "top": ["auto"],
+    "unicode-bidi": [],
+    "vertical-align": ["verticalAlign"],
+    "white-space": ["whiteSpace"],
+    "width": ["auto"],
+    "word-spacing": [],
+    "z-index": [],
+
+    "-moz-appearance": ["mozAppearance"],
+    "-moz-border-radius": [],
+    "-moz-border-radius-bottomleft": [],
+    "-moz-border-radius-bottomright": [],
+    "-moz-border-radius-topleft": [],
+    "-moz-border-radius-topright": [],
+    "-moz-border-top-colors": ["color", "systemColor"],
+    "-moz-border-right-colors": ["color", "systemColor"],
+    "-moz-border-bottom-colors": ["color", "systemColor"],
+    "-moz-border-left-colors": ["color", "systemColor"],
+    "-moz-box-align": ["mozBoxAlign"],
+    "-moz-box-direction": ["mozBoxDirection"],
+    "-moz-box-flex": [],
+    "-moz-box-ordinal-group": [],
+    "-moz-box-orient": ["mozBoxOrient"],
+    "-moz-box-pack": ["mozBoxPack"],
+    "-moz-box-sizing": ["mozBoxSizing"],
+    "-moz-opacity": [],
+    "-moz-user-focus": ["userFocus", "none"],
+    "-moz-user-input": ["userInput"],
+    "-moz-user-modify": [],
+    "-moz-user-select": ["userSelect", "none"],
+    "-moz-background-clip": [],
+    "-moz-background-inline-policy": [],
+    "-moz-background-origin": [],
+    "-moz-binding": [],
+    "-moz-column-count": [],
+    "-moz-column-gap": [],
+    "-moz-column-width": [],
+    "-moz-image-region": []
+};
+
+this.inheritedStyleNames =
+{
+    "border-collapse": 1,
+    "border-spacing": 1,
+    "border-style": 1,
+    "caption-side": 1,
+    "color": 1,
+    "cursor": 1,
+    "direction": 1,
+    "empty-cells": 1,
+    "font": 1,
+    "font-family": 1,
+    "font-size-adjust": 1,
+    "font-size": 1,
+    "font-style": 1,
+    "font-variant": 1,
+    "font-weight": 1,
+    "letter-spacing": 1,
+    "line-height": 1,
+    "list-style": 1,
+    "list-style-image": 1,
+    "list-style-position": 1,
+    "list-style-type": 1,
+    "quotes": 1,
+    "text-align": 1,
+    "text-decoration": 1,
+    "text-indent": 1,
+    "text-shadow": 1,
+    "text-transform": 1,
+    "white-space": 1,
+    "word-spacing": 1
+};
+
+this.cssKeywords =
+{
+    "appearance":
+    [
+        "button",
+        "button-small",
+        "checkbox",
+        "checkbox-container",
+        "checkbox-small",
+        "dialog",
+        "listbox",
+        "menuitem",
+        "menulist",
+        "menulist-button",
+        "menulist-textfield",
+        "menupopup",
+        "progressbar",
+        "radio",
+        "radio-container",
+        "radio-small",
+        "resizer",
+        "scrollbar",
+        "scrollbarbutton-down",
+        "scrollbarbutton-left",
+        "scrollbarbutton-right",
+        "scrollbarbutton-up",
+        "scrollbartrack-horizontal",
+        "scrollbartrack-vertical",
+        "separator",
+        "statusbar",
+        "tab",
+        "tab-left-edge",
+        "tabpanels",
+        "textfield",
+        "toolbar",
+        "toolbarbutton",
+        "toolbox",
+        "tooltip",
+        "treeheadercell",
+        "treeheadersortarrow",
+        "treeitem",
+        "treetwisty",
+        "treetwistyopen",
+        "treeview",
+        "window"
+    ],
+
+    "systemColor":
+    [
+        "ActiveBorder",
+        "ActiveCaption",
+        "AppWorkspace",
+        "Background",
+        "ButtonFace",
+        "ButtonHighlight",
+        "ButtonShadow",
+        "ButtonText",
+        "CaptionText",
+        "GrayText",
+        "Highlight",
+        "HighlightText",
+        "InactiveBorder",
+        "InactiveCaption",
+        "InactiveCaptionText",
+        "InfoBackground",
+        "InfoText",
+        "Menu",
+        "MenuText",
+        "Scrollbar",
+        "ThreeDDarkShadow",
+        "ThreeDFace",
+        "ThreeDHighlight",
+        "ThreeDLightShadow",
+        "ThreeDShadow",
+        "Window",
+        "WindowFrame",
+        "WindowText",
+        "-moz-field",
+        "-moz-fieldtext",
+        "-moz-workspace",
+        "-moz-visitedhyperlinktext",
+        "-moz-use-text-color"
+    ],
+
+    "color":
+    [
+        "AliceBlue",
+        "AntiqueWhite",
+        "Aqua",
+        "Aquamarine",
+        "Azure",
+        "Beige",
+        "Bisque",
+        "Black",
+        "BlanchedAlmond",
+        "Blue",
+        "BlueViolet",
+        "Brown",
+        "BurlyWood",
+        "CadetBlue",
+        "Chartreuse",
+        "Chocolate",
+        "Coral",
+        "CornflowerBlue",
+        "Cornsilk",
+        "Crimson",
+        "Cyan",
+        "DarkBlue",
+        "DarkCyan",
+        "DarkGoldenRod",
+        "DarkGray",
+        "DarkGreen",
+        "DarkKhaki",
+        "DarkMagenta",
+        "DarkOliveGreen",
+        "DarkOrange",
+        "DarkOrchid",
+        "DarkRed",
+        "DarkSalmon",
+        "DarkSeaGreen",
+        "DarkSlateBlue",
+        "DarkSlateGray",
+        "DarkTurquoise",
+        "DarkViolet",
+        "DeepPink",
+        "DarkSkyBlue",
+        "DimGray",
+        "DodgerBlue",
+        "Feldspar",
+        "FireBrick",
+        "FloralWhite",
+        "ForestGreen",
+        "Fuchsia",
+        "Gainsboro",
+        "GhostWhite",
+        "Gold",
+        "GoldenRod",
+        "Gray",
+        "Green",
+        "GreenYellow",
+        "HoneyDew",
+        "HotPink",
+        "IndianRed",
+        "Indigo",
+        "Ivory",
+        "Khaki",
+        "Lavender",
+        "LavenderBlush",
+        "LawnGreen",
+        "LemonChiffon",
+        "LightBlue",
+        "LightCoral",
+        "LightCyan",
+        "LightGoldenRodYellow",
+        "LightGrey",
+        "LightGreen",
+        "LightPink",
+        "LightSalmon",
+        "LightSeaGreen",
+        "LightSkyBlue",
+        "LightSlateBlue",
+        "LightSlateGray",
+        "LightSteelBlue",
+        "LightYellow",
+        "Lime",
+        "LimeGreen",
+        "Linen",
+        "Magenta",
+        "Maroon",
+        "MediumAquaMarine",
+        "MediumBlue",
+        "MediumOrchid",
+        "MediumPurple",
+        "MediumSeaGreen",
+        "MediumSlateBlue",
+        "MediumSpringGreen",
+        "MediumTurquoise",
+        "MediumVioletRed",
+        "MidnightBlue",
+        "MintCream",
+        "MistyRose",
+        "Moccasin",
+        "NavajoWhite",
+        "Navy",
+        "OldLace",
+        "Olive",
+        "OliveDrab",
+        "Orange",
+        "OrangeRed",
+        "Orchid",
+        "PaleGoldenRod",
+        "PaleGreen",
+        "PaleTurquoise",
+        "PaleVioletRed",
+        "PapayaWhip",
+        "PeachPuff",
+        "Peru",
+        "Pink",
+        "Plum",
+        "PowderBlue",
+        "Purple",
+        "Red",
+        "RosyBrown",
+        "RoyalBlue",
+        "SaddleBrown",
+        "Salmon",
+        "SandyBrown",
+        "SeaGreen",
+        "SeaShell",
+        "Sienna",
+        "Silver",
+        "SkyBlue",
+        "SlateBlue",
+        "SlateGray",
+        "Snow",
+        "SpringGreen",
+        "SteelBlue",
+        "Tan",
+        "Teal",
+        "Thistle",
+        "Tomato",
+        "Turquoise",
+        "Violet",
+        "VioletRed",
+        "Wheat",
+        "White",
+        "WhiteSmoke",
+        "Yellow",
+        "YellowGreen",
+        "transparent",
+        "invert"
+    ],
+
+    "auto":
+    [
+        "auto"
+    ],
+
+    "none":
+    [
+        "none"
+    ],
+
+    "captionSide":
+    [
+        "top",
+        "bottom",
+        "left",
+        "right"
+    ],
+
+    "clear":
+    [
+        "left",
+        "right",
+        "both"
+    ],
+
+    "cursor":
+    [
+        "auto",
+        "cell",
+        "context-menu",
+        "crosshair",
+        "default",
+        "help",
+        "pointer",
+        "progress",
+        "move",
+        "e-resize",
+        "all-scroll",
+        "ne-resize",
+        "nw-resize",
+        "n-resize",
+        "se-resize",
+        "sw-resize",
+        "s-resize",
+        "w-resize",
+        "ew-resize",
+        "ns-resize",
+        "nesw-resize",
+        "nwse-resize",
+        "col-resize",
+        "row-resize",
+        "text",
+        "vertical-text",
+        "wait",
+        "alias",
+        "copy",
+        "move",
+        "no-drop",
+        "not-allowed",
+        "-moz-alias",
+        "-moz-cell",
+        "-moz-copy",
+        "-moz-grab",
+        "-moz-grabbing",
+        "-moz-contextmenu",
+        "-moz-zoom-in",
+        "-moz-zoom-out",
+        "-moz-spinning"
+    ],
+
+    "direction":
+    [
+        "ltr",
+        "rtl"
+    ],
+
+    "bgAttachment":
+    [
+        "scroll",
+        "fixed"
+    ],
+
+    "bgPosition":
+    [
+        "top",
+        "center",
+        "bottom",
+        "left",
+        "right"
+    ],
+
+    "bgRepeat":
+    [
+        "repeat",
+        "repeat-x",
+        "repeat-y",
+        "no-repeat"
+    ],
+
+    "borderStyle":
+    [
+        "hidden",
+        "dotted",
+        "dashed",
+        "solid",
+        "double",
+        "groove",
+        "ridge",
+        "inset",
+        "outset",
+        "-moz-bg-inset",
+        "-moz-bg-outset",
+        "-moz-bg-solid"
+    ],
+
+    "borderCollapse":
+    [
+        "collapse",
+        "separate"
+    ],
+
+    "overflow":
+    [
+        "visible",
+        "hidden",
+        "scroll",
+        "-moz-scrollbars-horizontal",
+        "-moz-scrollbars-none",
+        "-moz-scrollbars-vertical"
+    ],
+
+    "listStyleType":
+    [
+        "disc",
+        "circle",
+        "square",
+        "decimal",
+        "decimal-leading-zero",
+        "lower-roman",
+        "upper-roman",
+        "lower-greek",
+        "lower-alpha",
+        "lower-latin",
+        "upper-alpha",
+        "upper-latin",
+        "hebrew",
+        "armenian",
+        "georgian",
+        "cjk-ideographic",
+        "hiragana",
+        "katakana",
+        "hiragana-iroha",
+        "katakana-iroha",
+        "inherit"
+    ],
+
+    "listStylePosition":
+    [
+        "inside",
+        "outside"
+    ],
+
+    "content":
+    [
+        "open-quote",
+        "close-quote",
+        "no-open-quote",
+        "no-close-quote",
+        "inherit"
+    ],
+
+    "fontStyle":
+    [
+        "normal",
+        "italic",
+        "oblique",
+        "inherit"
+    ],
+
+    "fontVariant":
+    [
+        "normal",
+        "small-caps",
+        "inherit"
+    ],
+
+    "fontWeight":
+    [
+        "normal",
+        "bold",
+        "bolder",
+        "lighter",
+        "inherit"
+    ],
+
+    "fontSize":
+    [
+        "xx-small",
+        "x-small",
+        "small",
+        "medium",
+        "large",
+        "x-large",
+        "xx-large",
+        "smaller",
+        "larger"
+    ],
+
+    "fontFamily":
+    [
+        "Arial",
+        "Comic Sans MS",
+        "Georgia",
+        "Tahoma",
+        "Verdana",
+        "Times New Roman",
+        "Trebuchet MS",
+        "Lucida Grande",
+        "Helvetica",
+        "serif",
+        "sans-serif",
+        "cursive",
+        "fantasy",
+        "monospace",
+        "caption",
+        "icon",
+        "menu",
+        "message-box",
+        "small-caption",
+        "status-bar",
+        "inherit"
+    ],
+
+    "display":
+    [
+        "block",
+        "inline",
+        "inline-block",
+        "list-item",
+        "marker",
+        "run-in",
+        "compact",
+        "table",
+        "inline-table",
+        "table-row-group",
+        "table-column",
+        "table-column-group",
+        "table-header-group",
+        "table-footer-group",
+        "table-row",
+        "table-cell",
+        "table-caption",
+        "-moz-box",
+        "-moz-compact",
+        "-moz-deck",
+        "-moz-grid",
+        "-moz-grid-group",
+        "-moz-grid-line",
+        "-moz-groupbox",
+        "-moz-inline-block",
+        "-moz-inline-box",
+        "-moz-inline-grid",
+        "-moz-inline-stack",
+        "-moz-inline-table",
+        "-moz-marker",
+        "-moz-popup",
+        "-moz-runin",
+        "-moz-stack"
+    ],
+
+    "position":
+    [
+        "static",
+        "relative",
+        "absolute",
+        "fixed",
+        "inherit"
+    ],
+
+    "float":
+    [
+        "left",
+        "right"
+    ],
+
+    "textAlign":
+    [
+        "left",
+        "right",
+        "center",
+        "justify"
+    ],
+
+    "tableLayout":
+    [
+        "fixed"
+    ],
+
+    "textDecoration":
+    [
+        "underline",
+        "overline",
+        "line-through",
+        "blink"
+    ],
+
+    "textTransform":
+    [
+        "capitalize",
+        "lowercase",
+        "uppercase",
+        "inherit"
+    ],
+
+    "unicodeBidi":
+    [
+        "normal",
+        "embed",
+        "bidi-override"
+    ],
+
+    "whiteSpace":
+    [
+        "normal",
+        "pre",
+        "nowrap"
+    ],
+
+    "verticalAlign":
+    [
+        "baseline",
+        "sub",
+        "super",
+        "top",
+        "text-top",
+        "middle",
+        "bottom",
+        "text-bottom",
+        "inherit"
+    ],
+
+    "thickness":
+    [
+        "thin",
+        "medium",
+        "thick"
+    ],
+
+    "userFocus":
+    [
+        "ignore",
+        "normal"
+    ],
+
+    "userInput":
+    [
+        "disabled",
+        "enabled"
+    ],
+
+    "userSelect":
+    [
+        "normal"
+    ],
+
+    "mozBoxSizing":
+    [
+        "content-box",
+        "padding-box",
+        "border-box"
+    ],
+
+    "mozBoxAlign":
+    [
+        "start",
+        "center",
+        "end",
+        "baseline",
+        "stretch"
+    ],
+
+    "mozBoxDirection":
+    [
+        "normal",
+        "reverse"
+    ],
+
+    "mozBoxOrient":
+    [
+        "horizontal",
+        "vertical"
+    ],
+
+    "mozBoxPack":
+    [
+        "start",
+        "center",
+        "end"
+    ]
+};
+
+this.nonEditableTags =
+{
+    "HTML": 1,
+    "HEAD": 1,
+    "html": 1,
+    "head": 1
+};
+
+this.innerEditableTags =
+{
+    "BODY": 1,
+    "body": 1
+};
+
+this.selfClosingTags =
+{ // End tags for void elements are forbidden http://wiki.whatwg.org/wiki/HTML_vs._XHTML
+    "meta": 1,
+    "link": 1,
+    "area": 1,
+    "base": 1,
+    "col": 1,
+    "input": 1,
+    "img": 1,
+    "br": 1,
+    "hr": 1,
+    "param":1,
+    "embed":1
+};
+
+var invisibleTags = this.invisibleTags =
+{
+    "HTML": 1,
+    "HEAD": 1,
+    "TITLE": 1,
+    "META": 1,
+    "LINK": 1,
+    "STYLE": 1,
+    "SCRIPT": 1,
+    "NOSCRIPT": 1,
+    "BR": 1,
+    "PARAM": 1,
+    "COL": 1,
+
+    "html": 1,
+    "head": 1,
+    "title": 1,
+    "meta": 1,
+    "link": 1,
+    "style": 1,
+    "script": 1,
+    "noscript": 1,
+    "br": 1,
+    "param": 1,
+    "col": 1
+    /*
+    "window": 1,
+    "browser": 1,
+    "frame": 1,
+    "tabbrowser": 1,
+    "WINDOW": 1,
+    "BROWSER": 1,
+    "FRAME": 1,
+    "TABBROWSER": 1,
+    */
+};
+
+
+if (typeof KeyEvent == "undefined") {
+    this.KeyEvent = {
+        DOM_VK_CANCEL: 3,
+        DOM_VK_HELP: 6,
+        DOM_VK_BACK_SPACE: 8,
+        DOM_VK_TAB: 9,
+        DOM_VK_CLEAR: 12,
+        DOM_VK_RETURN: 13,
+        DOM_VK_ENTER: 14,
+        DOM_VK_SHIFT: 16,
+        DOM_VK_CONTROL: 17,
+        DOM_VK_ALT: 18,
+        DOM_VK_PAUSE: 19,
+        DOM_VK_CAPS_LOCK: 20,
+        DOM_VK_ESCAPE: 27,
+        DOM_VK_SPACE: 32,
+        DOM_VK_PAGE_UP: 33,
+        DOM_VK_PAGE_DOWN: 34,
+        DOM_VK_END: 35,
+        DOM_VK_HOME: 36,
+        DOM_VK_LEFT: 37,
+        DOM_VK_UP: 38,
+        DOM_VK_RIGHT: 39,
+        DOM_VK_DOWN: 40,
+        DOM_VK_PRINTSCREEN: 44,
+        DOM_VK_INSERT: 45,
+        DOM_VK_DELETE: 46,
+        DOM_VK_0: 48,
+        DOM_VK_1: 49,
+        DOM_VK_2: 50,
+        DOM_VK_3: 51,
+        DOM_VK_4: 52,
+        DOM_VK_5: 53,
+        DOM_VK_6: 54,
+        DOM_VK_7: 55,
+        DOM_VK_8: 56,
+        DOM_VK_9: 57,
+        DOM_VK_SEMICOLON: 59,
+        DOM_VK_EQUALS: 61,
+        DOM_VK_A: 65,
+        DOM_VK_B: 66,
+        DOM_VK_C: 67,
+        DOM_VK_D: 68,
+        DOM_VK_E: 69,
+        DOM_VK_F: 70,
+        DOM_VK_G: 71,
+        DOM_VK_H: 72,
+        DOM_VK_I: 73,
+        DOM_VK_J: 74,
+        DOM_VK_K: 75,
+        DOM_VK_L: 76,
+        DOM_VK_M: 77,
+        DOM_VK_N: 78,
+        DOM_VK_O: 79,
+        DOM_VK_P: 80,
+        DOM_VK_Q: 81,
+        DOM_VK_R: 82,
+        DOM_VK_S: 83,
+        DOM_VK_T: 84,
+        DOM_VK_U: 85,
+        DOM_VK_V: 86,
+        DOM_VK_W: 87,
+        DOM_VK_X: 88,
+        DOM_VK_Y: 89,
+        DOM_VK_Z: 90,
+        DOM_VK_CONTEXT_MENU: 93,
+        DOM_VK_NUMPAD0: 96,
+        DOM_VK_NUMPAD1: 97,
+        DOM_VK_NUMPAD2: 98,
+        DOM_VK_NUMPAD3: 99,
+        DOM_VK_NUMPAD4: 100,
+        DOM_VK_NUMPAD5: 101,
+        DOM_VK_NUMPAD6: 102,
+        DOM_VK_NUMPAD7: 103,
+        DOM_VK_NUMPAD8: 104,
+        DOM_VK_NUMPAD9: 105,
+        DOM_VK_MULTIPLY: 106,
+        DOM_VK_ADD: 107,
+        DOM_VK_SEPARATOR: 108,
+        DOM_VK_SUBTRACT: 109,
+        DOM_VK_DECIMAL: 110,
+        DOM_VK_DIVIDE: 111,
+        DOM_VK_F1: 112,
+        DOM_VK_F2: 113,
+        DOM_VK_F3: 114,
+        DOM_VK_F4: 115,
+        DOM_VK_F5: 116,
+        DOM_VK_F6: 117,
+        DOM_VK_F7: 118,
+        DOM_VK_F8: 119,
+        DOM_VK_F9: 120,
+        DOM_VK_F10: 121,
+        DOM_VK_F11: 122,
+        DOM_VK_F12: 123,
+        DOM_VK_F13: 124,
+        DOM_VK_F14: 125,
+        DOM_VK_F15: 126,
+        DOM_VK_F16: 127,
+        DOM_VK_F17: 128,
+        DOM_VK_F18: 129,
+        DOM_VK_F19: 130,
+        DOM_VK_F20: 131,
+        DOM_VK_F21: 132,
+        DOM_VK_F22: 133,
+        DOM_VK_F23: 134,
+        DOM_VK_F24: 135,
+        DOM_VK_NUM_LOCK: 144,
+        DOM_VK_SCROLL_LOCK: 145,
+        DOM_VK_COMMA: 188,
+        DOM_VK_PERIOD: 190,
+        DOM_VK_SLASH: 191,
+        DOM_VK_BACK_QUOTE: 192,
+        DOM_VK_OPEN_BRACKET: 219,
+        DOM_VK_BACK_SLASH: 220,
+        DOM_VK_CLOSE_BRACKET: 221,
+        DOM_VK_QUOTE: 222,
+        DOM_VK_META: 224
+    };
+}
+
+
+// ************************************************************************************************
+// Ajax
+
+/**
+ * @namespace
+ */
+this.Ajax =
+{
+
+    requests: [],
+    transport: null,
+    states: ["Uninitialized","Loading","Loaded","Interactive","Complete"],
+
+    initialize: function()
+    {
+        this.transport = FBL.getNativeXHRObject();
+    },
+
+    getXHRObject: function()
+    {
+        var xhrObj = false;
+        try
+        {
+            xhrObj = new XMLHttpRequest();
+        }
+        catch(e)
+        {
+            var progid = [
+                    "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0",
+                    "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"
+                ];
+
+            for ( var i=0; i < progid.length; ++i ) {
+                try
+                {
+                    xhrObj = new ActiveXObject(progid[i]);
+                }
+                catch(e)
+                {
+                    continue;
+                }
+                break;
+            }
+        }
+        finally
+        {
+            return xhrObj;
+        }
+    },
+
+
+    /**
+     * Create a AJAX request.
+     *
+     * @name request
+     * @param {Object}   options               request options
+     * @param {String}   options.url           URL to be requested
+     * @param {String}   options.type          Request type ("get" ou "post"). Default is "get".
+     * @param {Boolean}  options.async         Asynchronous flag. Default is "true".
+     * @param {String}   options.dataType      Data type ("text", "html", "xml" or "json"). Default is "text".
+     * @param {String}   options.contentType   Content-type of the data being sent. Default is "application/x-www-form-urlencoded".
+     * @param {Function} options.onLoading     onLoading callback
+     * @param {Function} options.onLoaded      onLoaded callback
+     * @param {Function} options.onInteractive onInteractive callback
+     * @param {Function} options.onComplete    onComplete callback
+     * @param {Function} options.onUpdate      onUpdate callback
+     * @param {Function} options.onSuccess     onSuccess callback
+     * @param {Function} options.onFailure     onFailure callback
+     */
+    request: function(options)
+    {
+        // process options
+        var o = FBL.extend(
+                {
+                    // default values
+                    type: "get",
+                    async: true,
+                    dataType: "text",
+                    contentType: "application/x-www-form-urlencoded"
+                },
+                options || {}
+            );
+
+        this.requests.push(o);
+
+        var s = this.getState();
+        if (s == "Uninitialized" || s == "Complete" || s == "Loaded")
+            this.sendRequest();
+    },
+
+    serialize: function(data)
+    {
+        var r = [""], rl = 0;
+        if (data) {
+            if (typeof data == "string")  r[rl++] = data;
+
+            else if (data.innerHTML && data.elements) {
+                for (var i=0,el,l=(el=data.elements).length; i < l; i++)
+                    if (el[i].name) {
+                        r[rl++] = encodeURIComponent(el[i].name);
+                        r[rl++] = "=";
+                        r[rl++] = encodeURIComponent(el[i].value);
+                        r[rl++] = "&";
+                    }
+
+            } else
+                for(var param in data) {
+                    r[rl++] = encodeURIComponent(param);
+                    r[rl++] = "=";
+                    r[rl++] = encodeURIComponent(data[param]);
+                    r[rl++] = "&";
+                }
+        }
+        return r.join("").replace(/&$/, "");
+    },
+
+    sendRequest: function()
+    {
+        var t = FBL.Ajax.transport, r = FBL.Ajax.requests.shift(), data;
+
+        // open XHR object
+        t.open(r.type, r.url, r.async);
+
+        //setRequestHeaders();
+
+        // indicates that it is a XHR request to the server
+        t.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+
+        // if data is being sent, sets the appropriate content-type
+        if (data = FBL.Ajax.serialize(r.data))
+            t.setRequestHeader("Content-Type", r.contentType);
+
+        /** @ignore */
+        // onreadystatechange handler
+        t.onreadystatechange = function()
+        {
+            FBL.Ajax.onStateChange(r);
+        };
+
+        // send the request
+        t.send(data);
+    },
+
+    /**
+     * Handles the state change
+     */
+    onStateChange: function(options)
+    {
+        var fn, o = options, t = this.transport;
+        var state = this.getState(t);
+
+        if (fn = o["on" + state]) fn(this.getResponse(o), o);
+
+        if (state == "Complete")
+        {
+            var success = t.status == 200, response = this.getResponse(o);
+
+            if (fn = o["onUpdate"])
+              fn(response, o);
+
+            if (fn = o["on" + (success ? "Success" : "Failure")])
+              fn(response, o);
+
+            t.onreadystatechange = FBL.emptyFn;
+
+            if (this.requests.length > 0)
+                setTimeout(this.sendRequest, 10);
+        }
+    },
+
+    /**
+     * gets the appropriate response value according the type
+     */
+    getResponse: function(options)
+    {
+        var t = this.transport, type = options.dataType;
+
+        if      (t.status != 200) return t.statusText;
+        else if (type == "text")  return t.responseText;
+        else if (type == "html")  return t.responseText;
+        else if (type == "xml")   return t.responseXML;
+        else if (type == "json")  return eval("(" + t.responseText + ")");
+    },
+
+    /**
+     * returns the current state of the XHR object
+     */
+    getState: function()
+    {
+        return this.states[this.transport.readyState];
+    }
+
+};
+
+
+// ************************************************************************************************
+// Cookie, from http://www.quirksmode.org/js/cookies.html
+
+this.createCookie = function(name,value,days)
+{
+    if ('cookie' in document)
+    {
+        if (days)
+        {
+            var date = new Date();
+            date.setTime(date.getTime()+(days*24*60*60*1000));
+            var expires = "; expires="+date.toGMTString();
+        }
+        else
+            var expires = "";
+
+        document.cookie = name+"="+value+expires+"; path=/";
+    }
+};
+
+this.readCookie = function (name)
+{
+    if ('cookie' in document)
+    {
+        var nameEQ = name + "=";
+        var ca = document.cookie.split(';');
+
+        for(var i=0; i < ca.length; i++)
+        {
+            var c = ca[i];
+            while (c.charAt(0)==' ') c = c.substring(1,c.length);
+            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
+        }
+    }
+
+    return null;
+};
+
+this.removeCookie = function(name)
+{
+    this.createCookie(name, "", -1);
+};
+
+
+// ************************************************************************************************
+// http://www.mister-pixel.com/#Content__state=is_that_simple
+var fixIE6BackgroundImageCache = function(doc)
+{
+    doc = doc || document;
+    try
+    {
+        doc.execCommand("BackgroundImageCache", false, true);
+    }
+    catch(E)
+    {
+
+    }
+};
+
+// ************************************************************************************************
+// calculatePixelsPerInch
+
+var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
+
+var calculatePixelsPerInch = function calculatePixelsPerInch(doc, body)
+{
+    var inch = FBL.createGlobalElement("div");
+    inch.style.cssText = resetStyle + "width:1in; height:1in; position:absolute; top:-1234px; left:-1234px;";
+    body.appendChild(inch);
+
+    FBL.pixelsPerInch = {
+        x: inch.offsetWidth,
+        y: inch.offsetHeight
+    };
+
+    body.removeChild(inch);
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.SourceLink = function(url, line, type, object, instance)
+{
+    this.href = url;
+    this.instance = instance;
+    this.line = line;
+    this.type = type;
+    this.object = object;
+};
+
+this.SourceLink.prototype =
+{
+    toString: function()
+    {
+        return this.href;
+    },
+    toJSON: function() // until 3.1...
+    {
+        return "{\"href\":\""+this.href+"\", "+
+            (this.line?("\"line\":"+this.line+","):"")+
+            (this.type?(" \"type\":\""+this.type+"\","):"")+
+                    "}";
+    }
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+this.SourceText = function(lines, owner)
+{
+    this.lines = lines;
+    this.owner = owner;
+};
+
+this.SourceText.getLineAsHTML = function(lineNo)
+{
+    return escapeForSourceLine(this.lines[lineNo-1]);
+};
+
+
+// ************************************************************************************************
+}).apply(FBL);
+
+/* See license.txt for terms of usage */
+
+FBL.ns( /** @scope s_i18n */ function() { with (FBL) {
+// ************************************************************************************************
+
+// TODO: xxxpedro localization
+var oSTR =
+{
+    "NoMembersWarning": "There are no properties to show for this object.",
+
+    "EmptyStyleSheet": "There are no rules in this stylesheet.",
+    "EmptyElementCSS": "This element has no style rules.",
+    "AccessRestricted": "Access to restricted URI denied.",
+
+    "net.label.Parameters": "Parameters",
+    "net.label.Source": "Source",
+    "URLParameters": "Params",
+
+    "EditStyle": "Edit Element Style...",
+    "NewRule": "New Rule...",
+
+    "NewProp": "New Property...",
+    "EditProp": 'Edit "%s"',
+    "DeleteProp": 'Delete "%s"',
+    "DisableProp": 'Disable "%s"'
+};
+
+// ************************************************************************************************
+
+FBL.$STR = function(name)
+{
+    return oSTR.hasOwnProperty(name) ? oSTR[name] : name;
+};
+
+FBL.$STRF = function(name, args)
+{
+    if (!oSTR.hasOwnProperty(name)) return name;
+
+    var format = oSTR[name];
+    var objIndex = 0;
+
+    var parts = parseFormat(format);
+    var trialIndex = objIndex;
+    var objects = args;
+
+    for (var i= 0; i < parts.length; i++)
+    {
+        var part = parts[i];
+        if (part && typeof(part) == "object")
+        {
+            if (++trialIndex > objects.length)  // then too few parameters for format, assume unformatted.
+            {
+                format = "";
+                objIndex = -1;
+                parts.length = 0;
+                break;
+            }
+        }
+
+    }
+
+    var result = [];
+    for (var i = 0; i < parts.length; ++i)
+    {
+        var part = parts[i];
+        if (part && typeof(part) == "object")
+        {
+            result.push(""+args.shift());
+        }
+        else
+            result.push(part);
+    }
+
+    return result.join("");
+};
+
+// ************************************************************************************************
+
+var parseFormat = function parseFormat(format)
+{
+    var parts = [];
+    if (format.length <= 0)
+        return parts;
+
+    var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/;
+    for (var m = reg.exec(format); m; m = reg.exec(format))
+    {
+        if (m[0].substr(0, 2) == "%%")
+        {
+            parts.push(format.substr(0, m.index));
+            parts.push(m[0].substr(1));
+        }
+        else
+        {
+            var type = m[8] ? m[8] : m[5];
+            var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+            var rep = null;
+            switch (type)
+            {
+                case "s":
+                    rep = FirebugReps.Text;
+                    break;
+                case "f":
+                case "i":
+                case "d":
+                    rep = FirebugReps.Number;
+                    break;
+                case "o":
+                    rep = null;
+                    break;
+            }
+
+            parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+            parts.push({rep: rep, precision: precision, type: ("%" + type)});
+        }
+
+        format = format.substr(m.index+m[0].length);
+    }
+
+    parts.push(format);
+    return parts;
+};
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns( /** @scope s_firebug */ function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Globals
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Internals
+
+var modules = [];
+var panelTypes = [];
+var panelTypeMap = {};
+var reps = [];
+
+var parentPanelMap = {};
+
+
+// ************************************************************************************************
+// Firebug
+
+/**
+ * @namespace describe Firebug
+ * @exports FBL.Firebug as Firebug
+ */
+FBL.Firebug =
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    version:  "Firebug Lite 1.4.0",
+    revision: "$Revision$",
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    modules: modules,
+    panelTypes: panelTypes,
+    panelTypeMap: panelTypeMap,
+    reps: reps,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Initialization
+
+    initialize: function()
+    {
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.initialize", "initializing application");
+
+        Firebug.browser = new Context(Env.browser);
+        Firebug.context = Firebug.browser;
+
+        Firebug.loadPrefs();
+        Firebug.context.persistedState.isOpen = false;
+
+        // Document must be cached before chrome initialization
+        cacheDocument();
+
+        if (Firebug.Inspector && Firebug.Inspector.create)
+            Firebug.Inspector.create();
+
+        if (FBL.CssAnalyzer && FBL.CssAnalyzer.processAllStyleSheets)
+            FBL.CssAnalyzer.processAllStyleSheets(Firebug.browser.document);
+
+        FirebugChrome.initialize();
+
+        dispatch(modules, "initialize", []);
+
+        if (Firebug.disableResourceFetching)
+            Firebug.Console.logFormatted(["Some Firebug Lite features are not working because " +
+            		"resource fetching is disabled. To enabled it set the Firebug Lite option " +
+            		"\"disableResourceFetching\" to \"false\". More info at " +
+            		"http://getfirebug.com/firebuglite#Options"],
+            		Firebug.context, "warn");
+
+        if (Env.onLoad)
+        {
+            var onLoad = Env.onLoad;
+            delete Env.onLoad;
+
+            setTimeout(onLoad, 200);
+        }
+    },
+
+    shutdown: function()
+    {
+        if (Firebug.saveCookies)
+            Firebug.savePrefs();
+
+        if (Firebug.Inspector)
+            Firebug.Inspector.destroy();
+
+        dispatch(modules, "shutdown", []);
+
+        var chromeMap = FirebugChrome.chromeMap;
+
+        for (var name in chromeMap)
+        {
+            if (chromeMap.hasOwnProperty(name))
+            {
+                try
+                {
+                    chromeMap[name].destroy();
+                }
+                catch(E)
+                {
+                    if (FBTrace.DBG_ERRORS) FBTrace.sysout("chrome.destroy() failed to: " + name);
+                }
+            }
+        }
+
+        Firebug.Lite.Cache.Element.clear();
+        Firebug.Lite.Cache.StyleSheet.clear();
+
+        Firebug.browser = null;
+        Firebug.context = null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Registration
+
+    registerModule: function()
+    {
+        modules.push.apply(modules, arguments);
+
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.registerModule");
+    },
+
+    registerPanel: function()
+    {
+        panelTypes.push.apply(panelTypes, arguments);
+
+        for (var i = 0, panelType; panelType = arguments[i]; ++i)
+        {
+            panelTypeMap[panelType.prototype.name] = arguments[i];
+
+            if (panelType.prototype.parentPanel)
+                parentPanelMap[panelType.prototype.parentPanel] = 1;
+        }
+
+        if (FBTrace.DBG_INITIALIZE)
+            for (var i = 0; i < arguments.length; ++i)
+                FBTrace.sysout("Firebug.registerPanel", arguments[i].prototype.name);
+    },
+
+    registerRep: function()
+    {
+        reps.push.apply(reps, arguments);
+    },
+
+    unregisterRep: function()
+    {
+        for (var i = 0; i < arguments.length; ++i)
+            remove(reps, arguments[i]);
+    },
+
+    setDefaultReps: function(funcRep, rep)
+    {
+        FBL.defaultRep = rep;
+        FBL.defaultFuncRep = funcRep;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Reps
+
+    getRep: function(object)
+    {
+        var type = typeof object;
+        if (isIE && isFunction(object))
+            type = "function";
+
+        for (var i = 0; i < reps.length; ++i)
+        {
+            var rep = reps[i];
+            try
+            {
+                if (rep.supportsObject(object, type))
+                {
+                    if (FBTrace.DBG_DOM)
+                        FBTrace.sysout("getRep type: "+type+" object: "+object, rep);
+                    return rep;
+                }
+            }
+            catch (exc)
+            {
+                if (FBTrace.DBG_ERRORS)
+                {
+                    FBTrace.sysout("firebug.getRep FAILS: ", exc.message || exc);
+                    FBTrace.sysout("firebug.getRep reps["+i+"/"+reps.length+"]: Rep="+reps[i].className);
+                    // TODO: xxxpedro add trace to FBTrace logs like in Firebug
+                    //firebug.trace();
+                }
+            }
+        }
+
+        return (type == 'function') ? defaultFuncRep : defaultRep;
+    },
+
+    getRepObject: function(node)
+    {
+        var target = null;
+        for (var child = node; child; child = child.parentNode)
+        {
+            if (hasClass(child, "repTarget"))
+                target = child;
+
+            if (child.repObject)
+            {
+                if (!target && hasClass(child, "repIgnore"))
+                    break;
+                else
+                    return child.repObject;
+            }
+        }
+    },
+
+    getRepNode: function(node)
+    {
+        for (var child = node; child; child = child.parentNode)
+        {
+            if (child.repObject)
+                return child;
+        }
+    },
+
+    getElementByRepObject: function(element, object)
+    {
+        for (var child = element.firstChild; child; child = child.nextSibling)
+        {
+            if (child.repObject == object)
+                return child;
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Preferences
+
+    getPref: function(name)
+    {
+        return Firebug[name];
+    },
+
+    setPref: function(name, value)
+    {
+        Firebug[name] = value;
+
+        Firebug.savePrefs();
+    },
+
+    setPrefs: function(prefs)
+    {
+        for (var name in prefs)
+        {
+            if (prefs.hasOwnProperty(name))
+                Firebug[name] = prefs[name];
+        }
+
+        Firebug.savePrefs();
+    },
+
+    restorePrefs: function()
+    {
+        var Options = Env.DefaultOptions;
+
+        for (var name in Options)
+        {
+            Firebug[name] = Options[name];
+        }
+    },
+
+    loadPrefs: function()
+    {
+        this.restorePrefs();
+
+        var prefs = Store.get("FirebugLite") || {};
+        var options = prefs.options;
+        var persistedState = prefs.persistedState || FBL.defaultPersistedState;
+
+        for (var name in options)
+        {
+            if (options.hasOwnProperty(name))
+                Firebug[name] = options[name];
+        }
+
+        if (Firebug.context && persistedState)
+            Firebug.context.persistedState = persistedState;
+    },
+
+    savePrefs: function()
+    {
+        var prefs = {
+            options: {}
+        };
+
+        var EnvOptions = Env.Options;
+        var options = prefs.options;
+        for (var name in EnvOptions)
+        {
+            if (EnvOptions.hasOwnProperty(name))
+            {
+                options[name] = Firebug[name];
+            }
+        }
+
+        var persistedState = Firebug.context.persistedState;
+        if (!persistedState)
+        {
+            persistedState = Firebug.context.persistedState = FBL.defaultPersistedState;
+        }
+
+        prefs.persistedState = persistedState;
+
+        Store.set("FirebugLite", prefs);
+    },
+
+    erasePrefs: function()
+    {
+        Store.remove("FirebugLite");
+        this.restorePrefs();
+    }
+};
+
+Firebug.restorePrefs();
+
+// xxxpedro should we remove this?
+window.Firebug = FBL.Firebug;
+
+if (!Env.Options.enablePersistent ||
+     Env.Options.enablePersistent && Env.isChromeContext ||
+     Env.isDebugMode)
+        Env.browser.window.Firebug = FBL.Firebug;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Other methods
+
+FBL.cacheDocument = function cacheDocument()
+{
+    var ElementCache = Firebug.Lite.Cache.Element;
+    var els = Firebug.browser.document.getElementsByTagName("*");
+    for (var i=0, l=els.length, el; i<l; i++)
+    {
+        el = els[i];
+        ElementCache(el);
+    }
+};
+
+// ************************************************************************************************
+
+/**
+ * @class
+ *
+ * Support for listeners registration. This object also extended by Firebug.Module so,
+ * all modules supports listening automatically. Notice that array of listeners
+ * is created for each intance of a module within initialize method. Thus all derived
+ * module classes must ensure that Firebug.Module.initialize method is called for the
+ * super class.
+ */
+Firebug.Listener = function()
+{
+    // The array is created when the first listeners is added.
+    // It can't be created here since derived objects would share
+    // the same array.
+    this.fbListeners = null;
+};
+
+Firebug.Listener.prototype =
+{
+    addListener: function(listener)
+    {
+        if (!this.fbListeners)
+            this.fbListeners = []; // delay the creation until the objects are created so 'this' causes new array for each module
+
+        this.fbListeners.push(listener);
+    },
+
+    removeListener: function(listener)
+    {
+        remove(this.fbListeners, listener);  // if this.fbListeners is null, remove is being called with no add
+    }
+};
+
+// ************************************************************************************************
+
+
+// ************************************************************************************************
+// Module
+
+/**
+ * @module Base class for all modules. Every derived module object must be registered using
+ * <code>Firebug.registerModule</code> method. There is always one instance of a module object
+ * per browser window.
+ * @extends Firebug.Listener
+ */
+Firebug.Module = extend(new Firebug.Listener(),
+/** @extend Firebug.Module */
+{
+    /**
+     * Called when the window is opened.
+     */
+    initialize: function()
+    {
+    },
+
+    /**
+     * Called when the window is closed.
+     */
+    shutdown: function()
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    /**
+     * Called when a new context is created but before the page is loaded.
+     */
+    initContext: function(context)
+    {
+    },
+
+    /**
+     * Called after a context is detached to a separate window;
+     */
+    reattachContext: function(browser, context)
+    {
+    },
+
+    /**
+     * Called when a context is destroyed. Module may store info on persistedState for reloaded pages.
+     */
+    destroyContext: function(context, persistedState)
+    {
+    },
+
+    // Called when a FF tab is create or activated (user changes FF tab)
+    // Called after context is created or with context == null (to abort?)
+    showContext: function(browser, context)
+    {
+    },
+
+    /**
+     * Called after a context's page gets DOMContentLoaded
+     */
+    loadedContext: function(context)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    showPanel: function(browser, panel)
+    {
+    },
+
+    showSidePanel: function(browser, panel)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    updateOption: function(name, value)
+    {
+    },
+
+    getObjectByURL: function(context, url)
+    {
+    }
+});
+
+// ************************************************************************************************
+// Panel
+
+/**
+ * @panel Base class for all panels. Every derived panel must define a constructor and
+ * register with "Firebug.registerPanel" method. An instance of the panel
+ * object is created by the framework for each browser tab where Firebug is activated.
+ */
+Firebug.Panel =
+{
+    name: "HelloWorld",
+    title: "Hello World!",
+
+    parentPanel: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    options: {
+        hasCommandLine: false,
+        hasStatusBar: false,
+        hasToolButtons: false,
+
+        // Pre-rendered panels are those included in the skin file (firebug.html)
+        isPreRendered: false,
+        innerHTMLSync: false
+
+        /*
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // To be used by external extensions
+        panelHTML: "",
+        panelCSS: "",
+
+        toolButtonsHTML: ""
+        /**/
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    tabNode: null,
+    panelNode: null,
+    sidePanelNode: null,
+    statusBarNode: null,
+    toolButtonsNode: null,
+
+    panelBarNode: null,
+
+    sidePanelBarBoxNode: null,
+    sidePanelBarNode: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    sidePanelBar: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    searchable: false,
+    editable: true,
+    order: 2147483647,
+    statusSeparator: "<",
+
+    create: function(context, doc)
+    {
+        this.hasSidePanel = parentPanelMap.hasOwnProperty(this.name);
+
+        this.panelBarNode = $("fbPanelBar1");
+        this.sidePanelBarBoxNode = $("fbPanelBar2");
+
+        if (this.hasSidePanel)
+        {
+            this.sidePanelBar = extend({}, PanelBar);
+            this.sidePanelBar.create(this);
+        }
+
+        var options = this.options = extend(Firebug.Panel.options, this.options);
+        var panelId = "fb" + this.name;
+
+        if (options.isPreRendered)
+        {
+            this.panelNode = $(panelId);
+
+            this.tabNode = $(panelId + "Tab");
+            this.tabNode.style.display = "block";
+
+            if (options.hasToolButtons)
+            {
+                this.toolButtonsNode = $(panelId + "Buttons");
+            }
+
+            if (options.hasStatusBar)
+            {
+                this.statusBarBox = $("fbStatusBarBox");
+                this.statusBarNode = $(panelId + "StatusBar");
+            }
+        }
+        else
+        {
+            var containerSufix = this.parentPanel ? "2" : "1";
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            // Create Panel
+            var panelNode = this.panelNode = createElement("div", {
+                id: panelId,
+                className: "fbPanel"
+            });
+
+            $("fbPanel" + containerSufix).appendChild(panelNode);
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            // Create Panel Tab
+            var tabHTML = '<span class="fbTabL"></span><span class="fbTabText">' +
+                    this.title + '</span><span class="fbTabR"></span>';
+
+            var tabNode = this.tabNode = createElement("a", {
+                id: panelId + "Tab",
+                className: "fbTab fbHover",
+                innerHTML: tabHTML
+            });
+
+            if (isIE6)
+            {
+                tabNode.href = "javascript:void(0)";
+            }
+
+            var panelBarNode = this.parentPanel ?
+                    Firebug.chrome.getPanel(this.parentPanel).sidePanelBarNode :
+                    this.panelBarNode;
+
+            panelBarNode.appendChild(tabNode);
+            tabNode.style.display = "block";
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            // create ToolButtons
+            if (options.hasToolButtons)
+            {
+                this.toolButtonsNode = createElement("span", {
+                    id: panelId + "Buttons",
+                    className: "fbToolbarButtons"
+                });
+
+                $("fbToolbarButtons").appendChild(this.toolButtonsNode);
+            }
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            // create StatusBar
+            if (options.hasStatusBar)
+            {
+                this.statusBarBox = $("fbStatusBarBox");
+
+                this.statusBarNode = createElement("span", {
+                    id: panelId + "StatusBar",
+                    className: "fbToolbarButtons fbStatusBar"
+                });
+
+                this.statusBarBox.appendChild(this.statusBarNode);
+            }
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            // create SidePanel
+        }
+
+        this.containerNode = this.panelNode.parentNode;
+
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.create", this.name);
+
+        // xxxpedro contextMenu
+        this.onContextMenu = bind(this.onContextMenu, this);
+
+        /*
+        this.context = context;
+        this.document = doc;
+
+        this.panelNode = doc.createElement("div");
+        this.panelNode.ownerPanel = this;
+
+        setClass(this.panelNode, "panelNode panelNode-"+this.name+" contextUID="+context.uid);
+        doc.body.appendChild(this.panelNode);
+
+        if (FBTrace.DBG_INITIALIZE)
+            FBTrace.sysout("firebug.initialize panelNode for "+this.name+"\n");
+
+        this.initializeNode(this.panelNode);
+        /**/
+    },
+
+    destroy: function(state) // Panel may store info on state
+    {
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.destroy", this.name);
+
+        if (this.hasSidePanel)
+        {
+            this.sidePanelBar.destroy();
+            this.sidePanelBar = null;
+        }
+
+        this.options = null;
+        this.name = null;
+        this.parentPanel = null;
+
+        this.tabNode = null;
+        this.panelNode = null;
+        this.containerNode = null;
+
+        this.toolButtonsNode = null;
+        this.statusBarBox = null;
+        this.statusBarNode = null;
+
+        //if (this.panelNode)
+        //    delete this.panelNode.ownerPanel;
+
+        //this.destroyNode();
+    },
+
+    initialize: function()
+    {
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.initialize", this.name);
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        if (this.hasSidePanel)
+        {
+            this.sidePanelBar.initialize();
+        }
+
+        var options = this.options = extend(Firebug.Panel.options, this.options);
+        var panelId = "fb" + this.name;
+
+        this.panelNode = $(panelId);
+
+        this.tabNode = $(panelId + "Tab");
+        this.tabNode.style.display = "block";
+
+        if (options.hasStatusBar)
+        {
+            this.statusBarBox = $("fbStatusBarBox");
+            this.statusBarNode = $(panelId + "StatusBar");
+        }
+
+        if (options.hasToolButtons)
+        {
+            this.toolButtonsNode = $(panelId + "Buttons");
+        }
+
+        this.containerNode = this.panelNode.parentNode;
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // restore persistent state
+        this.containerNode.scrollTop = this.lastScrollTop;
+
+        // xxxpedro contextMenu
+        addEvent(this.containerNode, "contextmenu", this.onContextMenu);
+
+
+        /// TODO: xxxpedro infoTip Hack
+        Firebug.chrome.currentPanel =
+                Firebug.chrome.selectedPanel && Firebug.chrome.selectedPanel.sidePanelBar ?
+                Firebug.chrome.selectedPanel.sidePanelBar.selectedPanel :
+                Firebug.chrome.selectedPanel;
+
+        Firebug.showInfoTips = true;
+        if (Firebug.InfoTip)
+            Firebug.InfoTip.initializeBrowser(Firebug.chrome);
+    },
+
+    shutdown: function()
+    {
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.Panel.shutdown", this.name);
+
+        /// TODO: xxxpedro infoTip Hack
+        if (Firebug.InfoTip)
+            Firebug.InfoTip.uninitializeBrowser(Firebug.chrome);
+
+        if (Firebug.chrome.largeCommandLineVisible)
+            Firebug.chrome.hideLargeCommandLine();
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        if (this.hasSidePanel)
+        {
+            // TODO: xxxpedro firebug1.3a6
+            // new PanelBar mechanism will need to call shutdown to hide the panels (so it
+            // doesn't appears in other panel's sidePanelBar. Therefore, we need to implement
+            // a "remember selected panel" feature in the sidePanelBar
+            //this.sidePanelBar.shutdown();
+        }
+
+        // store persistent state
+        this.lastScrollTop = this.containerNode.scrollTop;
+
+        // xxxpedro contextMenu
+        removeEvent(this.containerNode, "contextmenu", this.onContextMenu);
+    },
+
+    detach: function(oldChrome, newChrome)
+    {
+        if (oldChrome && oldChrome.selectedPanel && oldChrome.selectedPanel.name == this.name)
+            this.lastScrollTop = oldChrome.selectedPanel.containerNode.scrollTop;
+    },
+
+    reattach: function(doc)
+    {
+        if (this.options.innerHTMLSync)
+            this.synchronizeUI();
+    },
+
+    synchronizeUI: function()
+    {
+        this.containerNode.scrollTop = this.lastScrollTop || 0;
+    },
+
+    show: function(state)
+    {
+        var options = this.options;
+
+        if (options.hasStatusBar)
+        {
+            this.statusBarBox.style.display = "inline";
+            this.statusBarNode.style.display = "inline";
+        }
+
+        if (options.hasToolButtons)
+        {
+            this.toolButtonsNode.style.display = "inline";
+        }
+
+        this.panelNode.style.display = "block";
+
+        this.visible = true;
+
+        if (!this.parentPanel)
+            Firebug.chrome.layout(this);
+    },
+
+    hide: function(state)
+    {
+        var options = this.options;
+
+        if (options.hasStatusBar)
+        {
+            this.statusBarBox.style.display = "none";
+            this.statusBarNode.style.display = "none";
+        }
+
+        if (options.hasToolButtons)
+        {
+            this.toolButtonsNode.style.display = "none";
+        }
+
+        this.panelNode.style.display = "none";
+
+        this.visible = false;
+    },
+
+    watchWindow: function(win)
+    {
+    },
+
+    unwatchWindow: function(win)
+    {
+    },
+
+    updateOption: function(name, value)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    /**
+     * Toolbar helpers
+     */
+    showToolbarButtons: function(buttonsId, show)
+    {
+        try
+        {
+            if (!this.context.browser) // XXXjjb this is bug. Somehow the panel context is not FirebugContext.
+            {
+                if (FBTrace.DBG_ERRORS)
+                    FBTrace.sysout("firebug.Panel showToolbarButtons this.context has no browser, this:", this);
+
+                return;
+            }
+            var buttons = this.context.browser.chrome.$(buttonsId);
+            if (buttons)
+                collapse(buttons, show ? "false" : "true");
+        }
+        catch (exc)
+        {
+            if (FBTrace.DBG_ERRORS)
+            {
+                FBTrace.dumpProperties("firebug.Panel showToolbarButtons FAILS", exc);
+                if (!this.context.browser)FBTrace.dumpStack("firebug.Panel showToolbarButtons no browser");
+            }
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    /**
+     * Returns a number indicating the view's ability to inspect the object.
+     *
+     * Zero means not supported, and higher numbers indicate specificity.
+     */
+    supportsObject: function(object)
+    {
+        return 0;
+    },
+
+    hasObject: function(object)  // beyond type testing, is this object selectable?
+    {
+        return false;
+    },
+
+    select: function(object, forceUpdate)
+    {
+        if (!object)
+            object = this.getDefaultSelection(this.context);
+
+        if(FBTrace.DBG_PANELS)
+            FBTrace.sysout("firebug.select "+this.name+" forceUpdate: "+forceUpdate+" "+object+((object==this.selection)?"==":"!=")+this.selection);
+
+        if (forceUpdate || object != this.selection)
+        {
+            this.selection = object;
+            this.updateSelection(object);
+
+            // TODO: xxxpedro
+            // XXXjoe This is kind of cheating, but, feh.
+            //Firebug.chrome.onPanelSelect(object, this);
+            //if (uiListeners.length > 0)
+            //    dispatch(uiListeners, "onPanelSelect", [object, this]);  // TODO: make Firebug.chrome a uiListener
+        }
+    },
+
+    updateSelection: function(object)
+    {
+    },
+
+    markChange: function(skipSelf)
+    {
+        if (this.dependents)
+        {
+            if (skipSelf)
+            {
+                for (var i = 0; i < this.dependents.length; ++i)
+                {
+                    var panelName = this.dependents[i];
+                    if (panelName != this.name)
+                        this.context.invalidatePanels(panelName);
+                }
+            }
+            else
+                this.context.invalidatePanels.apply(this.context, this.dependents);
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    startInspecting: function()
+    {
+    },
+
+    stopInspecting: function(object, cancelled)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    search: function(text, reverse)
+    {
+    },
+
+    /**
+     * Retrieves the search options that this modules supports.
+     * This is used by the search UI to present the proper options.
+     */
+    getSearchOptionsMenuItems: function()
+    {
+        return [
+            Firebug.Search.searchOptionMenu("search.Case Sensitive", "searchCaseSensitive")
+        ];
+    },
+
+    /**
+     * Navigates to the next document whose match parameter returns true.
+     */
+    navigateToNextDocument: function(match, reverse)
+    {
+        // This is an approximation of the UI that is displayed by the location
+        // selector. This should be close enough, although it may be better
+        // to simply generate the sorted list within the module, rather than
+        // sorting within the UI.
+        var self = this;
+        function compare(a, b) {
+            var locA = self.getObjectDescription(a);
+            var locB = self.getObjectDescription(b);
+            if(locA.path > locB.path)
+                return 1;
+            if(locA.path < locB.path)
+                return -1;
+            if(locA.name > locB.name)
+                return 1;
+            if(locA.name < locB.name)
+                return -1;
+            return 0;
+        }
+        var allLocs = this.getLocationList().sort(compare);
+        for (var curPos = 0; curPos < allLocs.length && allLocs[curPos] != this.location; curPos++);
+
+        function transformIndex(index) {
+            if (reverse) {
+                // For the reverse case we need to implement wrap around.
+                var intermediate = curPos - index - 1;
+                return (intermediate < 0 ? allLocs.length : 0) + intermediate;
+            } else {
+                return (curPos + index + 1) % allLocs.length;
+            }
+        };
+
+        for (var next = 0; next < allLocs.length - 1; next++)
+        {
+            var object = allLocs[transformIndex(next)];
+
+            if (match(object))
+            {
+                this.navigate(object);
+                return object;
+            }
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    // Called when "Options" clicked. Return array of
+    // {label: 'name', nol10n: true,  type: "checkbox", checked: <value>, command:function to set <value>}
+    getOptionsMenuItems: function()
+    {
+        return null;
+    },
+
+    /*
+     * Called by chrome.onContextMenu to build the context menu when this panel has focus.
+     * See also FirebugRep for a similar function also called by onContextMenu
+     * Extensions may monkey patch and chain off this call
+     * @param object: the 'realObject', a model value, eg a DOM property
+     * @param target: the HTML element clicked on.
+     * @return an array of menu items.
+     */
+    getContextMenuItems: function(object, target)
+    {
+        return [];
+    },
+
+    getBreakOnMenuItems: function()
+    {
+        return [];
+    },
+
+    getEditor: function(target, value)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getDefaultSelection: function()
+    {
+        return null;
+    },
+
+    browseObject: function(object)
+    {
+    },
+
+    getPopupObject: function(target)
+    {
+        return Firebug.getRepObject(target);
+    },
+
+    getTooltipObject: function(target)
+    {
+        return Firebug.getRepObject(target);
+    },
+
+    showInfoTip: function(infoTip, x, y)
+    {
+
+    },
+
+    getObjectPath: function(object)
+    {
+        return null;
+    },
+
+    // An array of objects that can be passed to getObjectLocation.
+    // The list of things a panel can show, eg sourceFiles.
+    // Only shown if panel.location defined and supportsObject true
+    getLocationList: function()
+    {
+        return null;
+    },
+
+    getDefaultLocation: function()
+    {
+        return null;
+    },
+
+    getObjectLocation: function(object)
+    {
+        return "";
+    },
+
+    // Text for the location list menu eg script panel source file list
+    // return.path: group/category label, return.name: item label
+    getObjectDescription: function(object)
+    {
+        var url = this.getObjectLocation(object);
+        return FBL.splitURLBase(url);
+    },
+
+    /*
+     *  UI signal that a tab needs attention, eg Script panel is currently stopped on a breakpoint
+     *  @param: show boolean, true turns on.
+     */
+    highlight: function(show)
+    {
+        var tab = this.getTab();
+        if (!tab)
+            return;
+
+        if (show)
+            tab.setAttribute("highlight", "true");
+        else
+            tab.removeAttribute("highlight");
+    },
+
+    getTab: function()
+    {
+        var chrome = Firebug.chrome;
+
+        var tab = chrome.$("fbPanelBar2").getTab(this.name);
+        if (!tab)
+            tab = chrome.$("fbPanelBar1").getTab(this.name);
+        return tab;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Support for Break On Next
+
+    /**
+     * Called by the framework when the user clicks on the Break On Next button.
+     * @param {Boolean} armed Set to true if the Break On Next feature is
+     * to be armed for action and set to false if the Break On Next should be disarmed.
+     * If 'armed' is true, then the next call to shouldBreakOnNext should be |true|.
+     */
+    breakOnNext: function(armed)
+    {
+    },
+
+    /**
+     * Called when a panel is selected/displayed. The method should return true
+     * if the Break On Next feature is currently armed for this panel.
+     */
+    shouldBreakOnNext: function()
+    {
+        return false;
+    },
+
+    /**
+     * Returns labels for Break On Next tooltip (one for enabled and one for disabled state).
+     * @param {Boolean} enabled Set to true if the Break On Next feature is
+     * currently activated for this panel.
+     */
+    getBreakOnNextTooltip: function(enabled)
+    {
+        return null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    // xxxpedro contextMenu
+    onContextMenu: function(event)
+    {
+        if (!this.getContextMenuItems)
+            return;
+
+        cancelEvent(event, true);
+
+        var target = event.target || event.srcElement;
+
+        var menu = this.getContextMenuItems(this.selection, target);
+        if (!menu)
+            return;
+
+        var contextMenu = new Menu(
+        {
+            id: "fbPanelContextMenu",
+
+            items: menu
+        });
+
+        contextMenu.show(event.clientX, event.clientY);
+
+        return true;
+
+        /*
+        // TODO: xxxpedro move code to somewhere. code to get cross-browser
+        // window to screen coordinates
+        var box = Firebug.browser.getElementPosition(Firebug.chrome.node);
+
+        var screenY = 0;
+
+        // Firefox
+        if (typeof window.mozInnerScreenY != "undefined")
+        {
+            screenY = window.mozInnerScreenY;
+        }
+        // Chrome
+        else if (typeof window.innerHeight != "undefined")
+        {
+            screenY = window.outerHeight - window.innerHeight;
+        }
+        // IE
+        else if (typeof window.screenTop != "undefined")
+        {
+            screenY = window.screenTop;
+        }
+
+        contextMenu.show(event.screenX-box.left, event.screenY-screenY-box.top);
+        /**/
+    }
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+/**
+ * MeasureBox
+ * To get pixels size.width and size.height:
+ * <ul><li>     this.startMeasuring(view); </li>
+ *     <li>     var size = this.measureText(lineNoCharsSpacer); </li>
+ *     <li>     this.stopMeasuring(); </li>
+ * </ul>
+ *
+ * @namespace
+ */
+Firebug.MeasureBox =
+{
+    startMeasuring: function(target)
+    {
+        if (!this.measureBox)
+        {
+            this.measureBox = target.ownerDocument.createElement("span");
+            this.measureBox.className = "measureBox";
+        }
+
+        copyTextStyles(target, this.measureBox);
+        target.ownerDocument.body.appendChild(this.measureBox);
+    },
+
+    getMeasuringElement: function()
+    {
+        return this.measureBox;
+    },
+
+    measureText: function(value)
+    {
+        this.measureBox.innerHTML = value ? escapeForSourceLine(value) : "m";
+        return {width: this.measureBox.offsetWidth, height: this.measureBox.offsetHeight-1};
+    },
+
+    measureInputText: function(value)
+    {
+        value = value ? escapeForTextNode(value) : "m";
+        if (!Firebug.showTextNodesWithWhitespace)
+            value = value.replace(/\t/g,'mmmmmm').replace(/\ /g,'m');
+        this.measureBox.innerHTML = value;
+        return {width: this.measureBox.offsetWidth, height: this.measureBox.offsetHeight-1};
+    },
+
+    getBox: function(target)
+    {
+        var style = this.measureBox.ownerDocument.defaultView.getComputedStyle(this.measureBox, "");
+        var box = getBoxFromStyles(style, this.measureBox);
+        return box;
+    },
+
+    stopMeasuring: function()
+    {
+        this.measureBox.parentNode.removeChild(this.measureBox);
+    }
+};
+
+
+// ************************************************************************************************
+if (FBL.domplate) Firebug.Rep = domplate(
+{
+    className: "",
+    inspectable: true,
+
+    supportsObject: function(object, type)
+    {
+        return false;
+    },
+
+    inspectObject: function(object, context)
+    {
+        Firebug.chrome.select(object);
+    },
+
+    browseObject: function(object, context)
+    {
+    },
+
+    persistObject: function(object, context)
+    {
+    },
+
+    getRealObject: function(object, context)
+    {
+        return object;
+    },
+
+    getTitle: function(object)
+    {
+        var label = safeToString(object);
+
+        var re = /\[object (.*?)\]/;
+        var m = re.exec(label);
+
+        ///return m ? m[1] : label;
+
+        // if the label is in the "[object TYPE]" format return its type
+        if (m)
+        {
+            return m[1];
+        }
+        // if it is IE we need to handle some special cases
+        else if (
+                // safeToString() fails to recognize some objects in IE
+                isIE &&
+                // safeToString() returns "[object]" for some objects like window.Image
+                (label == "[object]" ||
+                // safeToString() returns undefined for some objects like window.clientInformation
+                typeof object == "object" && typeof label == "undefined")
+            )
+        {
+            return "Object";
+        }
+        else
+        {
+            return label;
+        }
+    },
+
+    getTooltip: function(object)
+    {
+        return null;
+    },
+
+    getContextMenuItems: function(object, target, context)
+    {
+        return [];
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Convenience for domplates
+
+    STR: function(name)
+    {
+        return $STR(name);
+    },
+
+    cropString: function(text)
+    {
+        return cropString(text);
+    },
+
+    cropMultipleLines: function(text, limit)
+    {
+        return cropMultipleLines(text, limit);
+    },
+
+    toLowerCase: function(text)
+    {
+        return text ? text.toLowerCase() : text;
+    },
+
+    plural: function(n)
+    {
+        return n == 1 ? "" : "s";
+    }
+});
+
+// ************************************************************************************************
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns( /** @scope s_gui */ function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Controller
+
+/**@namespace*/
+FBL.Controller = {
+
+    controllers: null,
+    controllerContext: null,
+
+    initialize: function(context)
+    {
+        this.controllers = [];
+        this.controllerContext = context || Firebug.chrome;
+    },
+
+    shutdown: function()
+    {
+        this.removeControllers();
+
+        //this.controllers = null;
+        //this.controllerContext = null;
+    },
+
+    addController: function()
+    {
+        for (var i=0, arg; arg=arguments[i]; i++)
+        {
+            // If the first argument is a string, make a selector query
+            // within the controller node context
+            if (typeof arg[0] == "string")
+            {
+                arg[0] = $$(arg[0], this.controllerContext);
+            }
+
+            // bind the handler to the proper context
+            var handler = arg[2];
+            arg[2] = bind(handler, this);
+            // save the original handler as an extra-argument, so we can
+            // look for it later, when removing a particular controller
+            arg[3] = handler;
+
+            this.controllers.push(arg);
+            addEvent.apply(this, arg);
+        }
+    },
+
+    removeController: function()
+    {
+        for (var i=0, arg; arg=arguments[i]; i++)
+        {
+            for (var j=0, c; c=this.controllers[j]; j++)
+            {
+                if (arg[0] == c[0] && arg[1] == c[1] && arg[2] == c[3])
+                    removeEvent.apply(this, c);
+            }
+        }
+    },
+
+    removeControllers: function()
+    {
+        for (var i=0, c; c=this.controllers[i]; i++)
+        {
+            removeEvent.apply(this, c);
+        }
+    }
+};
+
+
+// ************************************************************************************************
+// PanelBar
+
+/**@namespace*/
+FBL.PanelBar =
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    panelMap: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    selectedPanel: null,
+    parentPanelName: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    create: function(ownerPanel)
+    {
+        this.panelMap = {};
+        this.ownerPanel = ownerPanel;
+
+        if (ownerPanel)
+        {
+            ownerPanel.sidePanelBarNode = createElement("span");
+            ownerPanel.sidePanelBarNode.style.display = "none";
+            ownerPanel.sidePanelBarBoxNode.appendChild(ownerPanel.sidePanelBarNode);
+        }
+
+        var panels = Firebug.panelTypes;
+        for (var i=0, p; p=panels[i]; i++)
+        {
+            if ( // normal Panel  of the Chrome's PanelBar
+                !ownerPanel && !p.prototype.parentPanel ||
+                // Child Panel of the current Panel's SidePanelBar
+                ownerPanel && p.prototype.parentPanel &&
+                ownerPanel.name == p.prototype.parentPanel)
+            {
+                this.addPanel(p.prototype.name);
+            }
+        }
+    },
+
+    destroy: function()
+    {
+        PanelBar.shutdown.call(this);
+
+        for (var name in this.panelMap)
+        {
+            this.removePanel(name);
+
+            var panel = this.panelMap[name];
+            panel.destroy();
+
+            this.panelMap[name] = null;
+            delete this.panelMap[name];
+        }
+
+        this.panelMap = null;
+        this.ownerPanel = null;
+    },
+
+    initialize: function()
+    {
+        if (this.ownerPanel)
+            this.ownerPanel.sidePanelBarNode.style.display = "inline";
+
+        for(var name in this.panelMap)
+        {
+            (function(self, name){
+
+                // tab click handler
+                var onTabClick = function onTabClick()
+                {
+                    self.selectPanel(name);
+                    return false;
+                };
+
+                Firebug.chrome.addController([self.panelMap[name].tabNode, "mousedown", onTabClick]);
+
+            })(this, name);
+        }
+    },
+
+    shutdown: function()
+    {
+        var selectedPanel = this.selectedPanel;
+
+        if (selectedPanel)
+        {
+            removeClass(selectedPanel.tabNode, "fbSelectedTab");
+            selectedPanel.hide();
+            selectedPanel.shutdown();
+        }
+
+        if (this.ownerPanel)
+            this.ownerPanel.sidePanelBarNode.style.display = "none";
+
+        this.selectedPanel = null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    addPanel: function(panelName, parentPanel)
+    {
+        var PanelType = Firebug.panelTypeMap[panelName];
+        var panel = this.panelMap[panelName] = new PanelType();
+
+        panel.create();
+    },
+
+    removePanel: function(panelName)
+    {
+        var panel = this.panelMap[panelName];
+        if (panel.hasOwnProperty(panelName))
+            panel.destroy();
+    },
+
+    selectPanel: function(panelName)
+    {
+        var selectedPanel = this.selectedPanel;
+        var panel = this.panelMap[panelName];
+
+        if (panel && selectedPanel != panel)
+        {
+            if (selectedPanel)
+            {
+                removeClass(selectedPanel.tabNode, "fbSelectedTab");
+                selectedPanel.shutdown();
+                selectedPanel.hide();
+            }
+
+            if (!panel.parentPanel)
+                Firebug.context.persistedState.selectedPanelName = panelName;
+
+            this.selectedPanel = panel;
+
+            setClass(panel.tabNode, "fbSelectedTab");
+            panel.show();
+            panel.initialize();
+        }
+    },
+
+    getPanel: function(panelName)
+    {
+        var panel = this.panelMap[panelName];
+
+        return panel;
+    }
+
+};
+
+//************************************************************************************************
+// Button
+
+/**
+ * options.element
+ * options.caption
+ * options.title
+ *
+ * options.owner
+ * options.className
+ * options.pressedClassName
+ *
+ * options.onPress
+ * options.onUnpress
+ * options.onClick
+ *
+ * @class
+ * @extends FBL.Controller
+ *
+ */
+
+FBL.Button = function(options)
+{
+    options = options || {};
+
+    append(this, options);
+
+    this.state = "unpressed";
+    this.display = "unpressed";
+
+    if (this.element)
+    {
+        this.container = this.element.parentNode;
+    }
+    else
+    {
+        this.shouldDestroy = true;
+
+        this.container = this.owner.getPanel().toolButtonsNode;
+
+        this.element = createElement("a", {
+            className: this.baseClassName + " " + this.className + " fbHover",
+            innerHTML: this.caption
+        });
+
+        if (this.title)
+            this.element.title = this.title;
+
+        this.container.appendChild(this.element);
+    }
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+Button.prototype = extend(Controller,
+/**@extend FBL.Button.prototype*/
+{
+    type: "normal",
+    caption: "caption",
+    title: null,
+
+    className: "", // custom class
+    baseClassName: "fbButton", // control class
+    pressedClassName: "fbBtnPressed", // control pressed class
+
+    element: null,
+    container: null,
+    owner: null,
+
+    state: null,
+    display: null,
+
+    destroy: function()
+    {
+        this.shutdown();
+
+        // only remove if it is a dynamically generated button (not pre-rendered)
+        if (this.shouldDestroy)
+            this.container.removeChild(this.element);
+
+        this.element = null;
+        this.container = null;
+        this.owner = null;
+    },
+
+    initialize: function()
+    {
+        Controller.initialize.apply(this);
+
+        var element = this.element;
+
+        this.addController([element, "mousedown", this.handlePress]);
+
+        if (this.type == "normal")
+            this.addController(
+                [element, "mouseup", this.handleUnpress],
+                [element, "mouseout", this.handleUnpress],
+                [element, "click", this.handleClick]
+            );
+    },
+
+    shutdown: function()
+    {
+        Controller.shutdown.apply(this);
+    },
+
+    restore: function()
+    {
+        this.changeState("unpressed");
+    },
+
+    changeState: function(state)
+    {
+        this.state = state;
+        this.changeDisplay(state);
+    },
+
+    changeDisplay: function(display)
+    {
+        if (display != this.display)
+        {
+            if (display == "pressed")
+            {
+                setClass(this.element, this.pressedClassName);
+            }
+            else if (display == "unpressed")
+            {
+                removeClass(this.element, this.pressedClassName);
+            }
+            this.display = display;
+        }
+    },
+
+    handlePress: function(event)
+    {
+        cancelEvent(event, true);
+
+        if (this.type == "normal")
+        {
+            this.changeDisplay("pressed");
+            this.beforeClick = true;
+        }
+        else if (this.type == "toggle")
+        {
+            if (this.state == "pressed")
+            {
+                this.changeState("unpressed");
+
+                if (this.onUnpress)
+                    this.onUnpress.apply(this.owner, arguments);
+            }
+            else
+            {
+                this.changeState("pressed");
+
+                if (this.onPress)
+                    this.onPress.apply(this.owner, arguments);
+            }
+
+            if (this.onClick)
+                this.onClick.apply(this.owner, arguments);
+        }
+
+        return false;
+    },
+
+    handleUnpress: function(event)
+    {
+        cancelEvent(event, true);
+
+        if (this.beforeClick)
+            this.changeDisplay("unpressed");
+
+        return false;
+    },
+
+    handleClick: function(event)
+    {
+        cancelEvent(event, true);
+
+        if (this.type == "normal")
+        {
+            if (this.onClick)
+                this.onClick.apply(this.owner);
+
+            this.changeState("unpressed");
+        }
+
+        this.beforeClick = false;
+
+        return false;
+    }
+});
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+/**
+ * @class
+ * @extends FBL.Button
+ */
+FBL.IconButton = function()
+{
+    Button.apply(this, arguments);
+};
+
+IconButton.prototype = extend(Button.prototype,
+/**@extend FBL.IconButton.prototype*/
+{
+    baseClassName: "fbIconButton",
+    pressedClassName: "fbIconPressed"
+});
+
+
+//************************************************************************************************
+// Menu
+
+var menuItemProps = {"class": "$item.className", type: "$item.type", value: "$item.value",
+        _command: "$item.command"};
+
+if (isIE6)
+    menuItemProps.href = "javascript:void(0)";
+
+// Allow GUI to be loaded even when Domplate module is not installed.
+if (FBL.domplate)
+var MenuPlate = domplate(Firebug.Rep,
+{
+    tag:
+        DIV({"class": "fbMenu fbShadow"},
+            DIV({"class": "fbMenuContent fbShadowContent"},
+                FOR("item", "$object.items|memberIterator",
+                    TAG("$item.tag", {item: "$item"})
+                )
+            )
+        ),
+
+    itemTag:
+        A(menuItemProps,
+            "$item.label"
+        ),
+
+    checkBoxTag:
+        A(extend(menuItemProps, {checked : "$item.checked"}),
+
+            "$item.label"
+        ),
+
+    radioButtonTag:
+        A(extend(menuItemProps, {selected : "$item.selected"}),
+
+            "$item.label"
+        ),
+
+    groupTag:
+        A(extend(menuItemProps, {child: "$item.child"}),
+            "$item.label"
+        ),
+
+    shortcutTag:
+        A(menuItemProps,
+            "$item.label",
+            SPAN({"class": "fbMenuShortcutKey"},
+                "$item.key"
+            )
+        ),
+
+    separatorTag:
+        SPAN({"class": "fbMenuSeparator"}),
+
+    memberIterator: function(items)
+    {
+        var result = [];
+
+        for (var i=0, length=items.length; i<length; i++)
+        {
+            var item = items[i];
+
+            // separator representation
+            if (typeof item == "string" && item.indexOf("-") == 0)
+            {
+                result.push({tag: this.separatorTag});
+                continue;
+            }
+
+            item = extend(item, {});
+
+            item.type = item.type || "";
+            item.value = item.value || "";
+
+            var type = item.type;
+
+            // default item representation
+            item.tag = this.itemTag;
+
+            var className = item.className || "";
+
+            className += "fbMenuOption fbHover ";
+
+            // specific representations
+            if (type == "checkbox")
+            {
+                className += "fbMenuCheckBox ";
+                item.tag = this.checkBoxTag;
+            }
+            else if (type == "radiobutton")
+            {
+                className += "fbMenuRadioButton ";
+                item.tag = this.radioButtonTag;
+            }
+            else if (type == "group")
+            {
+                className += "fbMenuGroup ";
+                item.tag = this.groupTag;
+            }
+            else if (type == "shortcut")
+            {
+                className += "fbMenuShortcut ";
+                item.tag = this.shortcutTag;
+            }
+
+            if (item.checked)
+                className += "fbMenuChecked ";
+            else if (item.selected)
+                className += "fbMenuRadioSelected ";
+
+            if (item.disabled)
+                className += "fbMenuDisabled ";
+
+            item.className = className;
+
+            item.label = $STR(item.label);
+
+            result.push(item);
+        }
+
+        return result;
+    }
+});
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+/**
+ * options
+ * options.element
+ * options.id
+ * options.items
+ *
+ * item.label
+ * item.className
+ * item.type
+ * item.value
+ * item.disabled
+ * item.checked
+ * item.selected
+ * item.command
+ * item.child
+ *
+ *
+ * @class
+ * @extends FBL.Controller
+ *
+ */
+FBL.Menu = function(options)
+{
+    // if element is not pre-rendered, we must render it now
+    if (!options.element)
+    {
+        if (options.getItems)
+            options.items = options.getItems();
+
+        options.element = MenuPlate.tag.append(
+                {object: options},
+                getElementByClass(Firebug.chrome.document, "fbBody"),
+                MenuPlate
+            );
+    }
+
+    // extend itself with the provided options
+    append(this, options);
+
+    if (typeof this.element == "string")
+    {
+        this.id = this.element;
+        this.element = $(this.id);
+    }
+    else if (this.id)
+    {
+        this.element.id = this.id;
+    }
+
+    this.element.firebugIgnore = true;
+    this.elementStyle = this.element.style;
+
+    this.isVisible = false;
+
+    this.handleMouseDown = bind(this.handleMouseDown, this);
+    this.handleMouseOver = bind(this.handleMouseOver, this);
+    this.handleMouseOut = bind(this.handleMouseOut, this);
+
+    this.handleWindowMouseDown = bind(this.handleWindowMouseDown, this);
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var menuMap = {};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+Menu.prototype =  extend(Controller,
+/**@extend FBL.Menu.prototype*/
+{
+    destroy: function()
+    {
+        //if (this.element) console.log("destroy", this.element.id);
+
+        this.hide();
+
+        // if it is a childMenu, remove its reference from the parentMenu
+        if (this.parentMenu)
+            this.parentMenu.childMenu = null;
+
+        // remove the element from the document
+        this.element.parentNode.removeChild(this.element);
+
+        // clear references
+        this.element = null;
+        this.elementStyle = null;
+        this.parentMenu = null;
+        this.parentTarget = null;
+    },
+
+    initialize: function()
+    {
+        Controller.initialize.call(this);
+
+        this.addController(
+                [this.element, "mousedown", this.handleMouseDown],
+                [this.element, "mouseover", this.handleMouseOver]
+             );
+    },
+
+    shutdown: function()
+    {
+        Controller.shutdown.call(this);
+    },
+
+    show: function(x, y)
+    {
+        this.initialize();
+
+        if (this.isVisible) return;
+
+        //console.log("show", this.element.id);
+
+        x = x || 0;
+        y = y || 0;
+
+        if (this.parentMenu)
+        {
+            var oldChildMenu = this.parentMenu.childMenu;
+            if (oldChildMenu && oldChildMenu != this)
+            {
+                oldChildMenu.destroy();
+            }
+
+            this.parentMenu.childMenu = this;
+        }
+        else
+            addEvent(Firebug.chrome.document, "mousedown", this.handleWindowMouseDown);
+
+        this.elementStyle.display = "block";
+        this.elementStyle.visibility = "hidden";
+
+        var size = Firebug.chrome.getSize();
+
+        x = Math.min(x, size.width - this.element.clientWidth - 10);
+        x = Math.max(x, 0);
+
+        y = Math.min(y, size.height - this.element.clientHeight - 10);
+        y = Math.max(y, 0);
+
+        this.elementStyle.left = x + "px";
+        this.elementStyle.top = y + "px";
+
+        this.elementStyle.visibility = "visible";
+
+        this.isVisible = true;
+
+        if (isFunction(this.onShow))
+            this.onShow.apply(this, arguments);
+    },
+
+    hide: function()
+    {
+        this.clearHideTimeout();
+        this.clearShowChildTimeout();
+
+        if (!this.isVisible) return;
+
+        //console.log("hide", this.element.id);
+
+        this.elementStyle.display = "none";
+
+        if(this.childMenu)
+        {
+            this.childMenu.destroy();
+            this.childMenu = null;
+        }
+
+        if(this.parentTarget)
+            removeClass(this.parentTarget, "fbMenuGroupSelected");
+
+        this.isVisible = false;
+
+        this.shutdown();
+
+        if (isFunction(this.onHide))
+            this.onHide.apply(this, arguments);
+    },
+
+    showChildMenu: function(target)
+    {
+        var id = target.getAttribute("child");
+
+        var parent = this;
+        var target = target;
+
+        this.showChildTimeout = Firebug.chrome.window.setTimeout(function(){
+
+            //if (!parent.isVisible) return;
+
+            var box = Firebug.chrome.getElementBox(target);
+
+            var childMenuObject = menuMap.hasOwnProperty(id) ?
+                    menuMap[id] : {element: $(id)};
+
+            var childMenu = new Menu(extend(childMenuObject,
+                {
+                    parentMenu: parent,
+                    parentTarget: target
+                }));
+
+            var offsetLeft = isIE6 ? -1 : -6; // IE6 problem with fixed position
+            childMenu.show(box.left + box.width + offsetLeft, box.top -6);
+            setClass(target, "fbMenuGroupSelected");
+
+        },350);
+    },
+
+    clearHideTimeout: function()
+    {
+        if (this.hideTimeout)
+        {
+            Firebug.chrome.window.clearTimeout(this.hideTimeout);
+            delete this.hideTimeout;
+        }
+    },
+
+    clearShowChildTimeout: function()
+    {
+        if(this.showChildTimeout)
+        {
+            Firebug.chrome.window.clearTimeout(this.showChildTimeout);
+            this.showChildTimeout = null;
+        }
+    },
+
+    handleMouseDown: function(event)
+    {
+        cancelEvent(event, true);
+
+        var topParent = this;
+        while (topParent.parentMenu)
+            topParent = topParent.parentMenu;
+
+        var target = event.target || event.srcElement;
+
+        target = getAncestorByClass(target, "fbMenuOption");
+
+        if(!target || hasClass(target, "fbMenuGroup"))
+            return false;
+
+        if (target && !hasClass(target, "fbMenuDisabled"))
+        {
+            var type = target.getAttribute("type");
+
+            if (type == "checkbox")
+            {
+                var checked = target.getAttribute("checked");
+                var value = target.getAttribute("value");
+                var wasChecked = hasClass(target, "fbMenuChecked");
+
+                if (wasChecked)
+                {
+                    removeClass(target, "fbMenuChecked");
+                    target.setAttribute("checked", "");
+                }
+                else
+                {
+                    setClass(target, "fbMenuChecked");
+                    target.setAttribute("checked", "true");
+                }
+
+                if (isFunction(this.onCheck))
+                    this.onCheck.call(this, target, value, !wasChecked);
+            }
+
+            if (type == "radiobutton")
+            {
+                var selectedRadios = getElementsByClass(target.parentNode, "fbMenuRadioSelected");
+
+                var group = target.getAttribute("group");
+
+                for (var i = 0, length = selectedRadios.length; i < length; i++)
+                {
+                    radio = selectedRadios[i];
+
+                    if (radio.getAttribute("group") == group)
+                    {
+                        removeClass(radio, "fbMenuRadioSelected");
+                        radio.setAttribute("selected", "");
+                    }
+                }
+
+                setClass(target, "fbMenuRadioSelected");
+                target.setAttribute("selected", "true");
+            }
+
+            var handler = null;
+
+            // target.command can be a function or a string.
+            var cmd = target.command;
+
+            // If it is a function it will be used as the handler
+            if (isFunction(cmd))
+                handler = cmd;
+            // If it is a string it the property of the current menu object
+            // will be used as the handler
+            else if (typeof cmd == "string")
+                handler = this[cmd];
+
+            var closeMenu = true;
+
+            if (handler)
+                closeMenu = handler.call(this, target) !== false;
+
+            if (closeMenu)
+                topParent.hide();
+        }
+
+        return false;
+    },
+
+    handleWindowMouseDown: function(event)
+    {
+        //console.log("handleWindowMouseDown");
+
+        var target = event.target || event.srcElement;
+
+        target = getAncestorByClass(target, "fbMenu");
+
+        if (!target)
+        {
+            removeEvent(Firebug.chrome.document, "mousedown", this.handleWindowMouseDown);
+            this.hide();
+        }
+    },
+
+    handleMouseOver: function(event)
+    {
+        //console.log("handleMouseOver", this.element.id);
+
+        this.clearHideTimeout();
+        this.clearShowChildTimeout();
+
+        var target = event.target || event.srcElement;
+
+        target = getAncestorByClass(target, "fbMenuOption");
+
+        if(!target)
+            return;
+
+        var childMenu = this.childMenu;
+        if(childMenu)
+        {
+            removeClass(childMenu.parentTarget, "fbMenuGroupSelected");
+
+            if (childMenu.parentTarget != target && childMenu.isVisible)
+            {
+                childMenu.clearHideTimeout();
+                childMenu.hideTimeout = Firebug.chrome.window.setTimeout(function(){
+                    childMenu.destroy();
+                },300);
+            }
+        }
+
+        if(hasClass(target, "fbMenuGroup"))
+        {
+            this.showChildMenu(target);
+        }
+    }
+});
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+append(Menu,
+/**@extend FBL.Menu*/
+{
+    register: function(object)
+    {
+        menuMap[object.id] = object;
+    },
+
+    check: function(element)
+    {
+        setClass(element, "fbMenuChecked");
+        element.setAttribute("checked", "true");
+    },
+
+    uncheck: function(element)
+    {
+        removeClass(element, "fbMenuChecked");
+        element.setAttribute("checked", "");
+    },
+
+    disable: function(element)
+    {
+        setClass(element, "fbMenuDisabled");
+    },
+
+    enable: function(element)
+    {
+        removeClass(element, "fbMenuDisabled");
+    }
+});
+
+
+//************************************************************************************************
+// Status Bar
+
+/**@class*/
+function StatusBar(){};
+
+StatusBar.prototype = extend(Controller, {
+
+});
+
+// ************************************************************************************************
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns( /**@scope s_context*/ function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Globals
+
+var refreshDelay = 300;
+
+// Opera and some versions of webkit returns the wrong value of document.elementFromPoint()
+// function, without taking into account the scroll position. Safari 4 (webkit/531.21.8)
+// still have this issue. Google Chrome 4 (webkit/532.5) does not. So, we're assuming this
+// issue was fixed in the 532 version
+var shouldFixElementFromPoint = isOpera || isSafari && browserVersion < "532";
+
+var evalError = "___firebug_evaluation_error___";
+var pixelsPerInch;
+
+var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
+var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;";
+
+
+// ************************************************************************************************
+// Context
+
+/** @class */
+FBL.Context = function(win)
+{
+    this.window = win.window;
+    this.document = win.document;
+
+    this.browser = Env.browser;
+
+    // Some windows in IE, like iframe, doesn't have the eval() method
+    if (isIE && !this.window.eval)
+    {
+        // But after executing the following line the method magically appears!
+        this.window.execScript("null");
+        // Just to make sure the "magic" really happened
+        if (!this.window.eval)
+            throw new Error("Firebug Error: eval() method not found in this window");
+    }
+
+    // Create a new "black-box" eval() method that runs in the global namespace
+    // of the context window, without exposing the local variables declared
+    // by the function that calls it
+    this.eval = this.window.eval("new Function('" +
+            "try{ return window.eval.apply(window,arguments) }catch(E){ E."+evalError+"=true; return E }" +
+        "')");
+};
+
+FBL.Context.prototype =
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // partial-port of Firebug tabContext.js
+
+    browser: null,
+    loaded: true,
+
+    setTimeout: function(fn, delay)
+    {
+        var win = this.window;
+
+        if (win.setTimeout == this.setTimeout)
+            throw new Error("setTimeout recursion");
+
+        var timeout = win.setTimeout.apply ? // IE doesn't have apply method on setTimeout
+                win.setTimeout.apply(win, arguments) :
+                win.setTimeout(fn, delay);
+
+        if (!this.timeouts)
+            this.timeouts = {};
+
+        this.timeouts[timeout] = 1;
+
+        return timeout;
+    },
+
+    clearTimeout: function(timeout)
+    {
+        clearTimeout(timeout);
+
+        if (this.timeouts)
+            delete this.timeouts[timeout];
+    },
+
+    setInterval: function(fn, delay)
+    {
+        var win = this.window;
+
+        var timeout = win.setInterval.apply ? // IE doesn't have apply method on setTimeout
+                win.setInterval.apply(win, arguments) :
+                win.setInterval(fn, delay);
+
+        if (!this.intervals)
+            this.intervals = {};
+
+        this.intervals[timeout] = 1;
+
+        return timeout;
+    },
+
+    clearInterval: function(timeout)
+    {
+        clearInterval(timeout);
+
+        if (this.intervals)
+            delete this.intervals[timeout];
+    },
+
+    invalidatePanels: function()
+    {
+        if (!this.invalidPanels)
+            this.invalidPanels = {};
+
+        for (var i = 0; i < arguments.length; ++i)
+        {
+            var panelName = arguments[i];
+
+            // avoid error. need to create a better getPanel() function as explained below
+            if (!Firebug.chrome || !Firebug.chrome.selectedPanel)
+                return;
+
+            //var panel = this.getPanel(panelName, true);
+            //TODO: xxxpedro context how to get all panels using a single function?
+            // the current workaround to make the invalidation works is invalidating
+            // only sidePanels. There's also a problem with panel name (LowerCase in Firebug Lite)
+            var panel = Firebug.chrome.selectedPanel.sidePanelBar ?
+                    Firebug.chrome.selectedPanel.sidePanelBar.getPanel(panelName, true) :
+                    null;
+
+            if (panel && !panel.noRefresh)
+                this.invalidPanels[panelName] = 1;
+        }
+
+        if (this.refreshTimeout)
+        {
+            this.clearTimeout(this.refreshTimeout);
+            delete this.refreshTimeout;
+        }
+
+        this.refreshTimeout = this.setTimeout(bindFixed(function()
+        {
+            var invalids = [];
+
+            for (var panelName in this.invalidPanels)
+            {
+                //var panel = this.getPanel(panelName, true);
+                //TODO: xxxpedro context how to get all panels using a single function?
+                // the current workaround to make the invalidation works is invalidating
+                // only sidePanels. There's also a problem with panel name (LowerCase in Firebug Lite)
+                var panel = Firebug.chrome.selectedPanel.sidePanelBar ?
+                        Firebug.chrome.selectedPanel.sidePanelBar.getPanel(panelName, true) :
+                        null;
+
+                if (panel)
+                {
+                    if (panel.visible && !panel.editing)
+                        panel.refresh();
+                    else
+                        panel.needsRefresh = true;
+
+                    // If the panel is being edited, we'll keep trying to
+                    // refresh it until editing is done
+                    if (panel.editing)
+                        invalids.push(panelName);
+                }
+            }
+
+            delete this.invalidPanels;
+            delete this.refreshTimeout;
+
+            // Keep looping until every tab is valid
+            if (invalids.length)
+                this.invalidatePanels.apply(this, invalids);
+        }, this), refreshDelay);
+    },
+
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Evalutation Method
+
+    /**
+     * Evaluates an expression in the current context window.
+     *
+     * @param {String}   expr           expression to be evaluated
+     *
+     * @param {String}   context        string indicating the global location
+     *                                  of the object that will be used as the
+     *                                  context. The context is referred in
+     *                                  the expression as the "this" keyword.
+     *                                  If no context is informed, the "window"
+     *                                  context is used.
+     *
+     * @param {String}   api            string indicating the global location
+     *                                  of the object that will be used as the
+     *                                  api of the evaluation.
+     *
+     * @param {Function} errorHandler(message) error handler to be called
+     *                                         if the evaluation fails.
+     */
+    evaluate: function(expr, context, api, errorHandler)
+    {
+        // the default context is the "window" object. It can be any string that represents
+        // a global accessible element as: "my.namespaced.object"
+        context = context || "window";
+
+        var isObjectLiteral = trim(expr).indexOf("{") == 0,
+            cmd,
+            result;
+
+        // if the context is the "window" object, we don't need a closure
+        if (context == "window")
+        {
+            // If it is an object literal, then wrap the expression with parenthesis so we can
+            // capture the return value
+            if (isObjectLiteral)
+            {
+                cmd = api ?
+                    "with("+api+"){ ("+expr+") }" :
+                    "(" + expr + ")";
+            }
+            else
+            {
+                cmd = api ?
+                    "with("+api+"){ "+expr+" }" :
+                    expr;
+            }
+        }
+        else
+        {
+            cmd = api ?
+                // with API and context, no return value
+                "(function(arguments){ with(" + api + "){ " +
+                    expr +
+                " } }).call(" + context + ",undefined)"
+                :
+                // with context only, no return value
+                "(function(arguments){ " +
+                    expr +
+                " }).call(" + context + ",undefined)";
+        }
+
+        result = this.eval(cmd);
+
+        if (result && result[evalError])
+        {
+            var msg = result.name ? (result.name + ": ") : "";
+            msg += result.message || result;
+
+            if (errorHandler)
+                result = errorHandler(msg);
+            else
+                result = msg;
+        }
+
+        return result;
+    },
+
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Window Methods
+
+    getWindowSize: function()
+    {
+        var width=0, height=0, el;
+
+        if (typeof this.window.innerWidth == "number")
+        {
+            width = this.window.innerWidth;
+            height = this.window.innerHeight;
+        }
+        else if ((el=this.document.documentElement) && (el.clientHeight || el.clientWidth))
+        {
+            width = el.clientWidth;
+            height = el.clientHeight;
+        }
+        else if ((el=this.document.body) && (el.clientHeight || el.clientWidth))
+        {
+            width = el.clientWidth;
+            height = el.clientHeight;
+        }
+
+        return {width: width, height: height};
+    },
+
+    getWindowScrollSize: function()
+    {
+        var width=0, height=0, el;
+
+        // first try the document.documentElement scroll size
+        if (!isIEQuiksMode && (el=this.document.documentElement) &&
+           (el.scrollHeight || el.scrollWidth))
+        {
+            width = el.scrollWidth;
+            height = el.scrollHeight;
+        }
+
+        // then we need to check if document.body has a bigger scroll size value
+        // because sometimes depending on the browser and the page, the document.body
+        // scroll size returns a smaller (and wrong) measure
+        if ((el=this.document.body) && (el.scrollHeight || el.scrollWidth) &&
+            (el.scrollWidth > width || el.scrollHeight > height))
+        {
+            width = el.scrollWidth;
+            height = el.scrollHeight;
+        }
+
+        return {width: width, height: height};
+    },
+
+    getWindowScrollPosition: function()
+    {
+        var top=0, left=0, el;
+
+        if(typeof this.window.pageYOffset == "number")
+        {
+            top = this.window.pageYOffset;
+            left = this.window.pageXOffset;
+        }
+        else if((el=this.document.body) && (el.scrollTop || el.scrollLeft))
+        {
+            top = el.scrollTop;
+            left = el.scrollLeft;
+        }
+        else if((el=this.document.documentElement) && (el.scrollTop || el.scrollLeft))
+        {
+            top = el.scrollTop;
+            left = el.scrollLeft;
+        }
+
+        return {top:top, left:left};
+    },
+
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Element Methods
+
+    getElementFromPoint: function(x, y)
+    {
+        if (shouldFixElementFromPoint)
+        {
+            var scroll = this.getWindowScrollPosition();
+            return this.document.elementFromPoint(x + scroll.left, y + scroll.top);
+        }
+        else
+            return this.document.elementFromPoint(x, y);
+    },
+
+    getElementPosition: function(el)
+    {
+        var left = 0;
+        var top = 0;
+
+        do
+        {
+            left += el.offsetLeft;
+            top += el.offsetTop;
+        }
+        while (el = el.offsetParent);
+
+        return {left:left, top:top};
+    },
+
+    getElementBox: function(el)
+    {
+        var result = {};
+
+        if (el.getBoundingClientRect)
+        {
+            var rect = el.getBoundingClientRect();
+
+            // fix IE problem with offset when not in fullscreen mode
+            var offset = isIE ? this.document.body.clientTop || this.document.documentElement.clientTop: 0;
+
+            var scroll = this.getWindowScrollPosition();
+
+            result.top = Math.round(rect.top - offset + scroll.top);
+            result.left = Math.round(rect.left - offset + scroll.left);
+            result.height = Math.round(rect.bottom - rect.top);
+            result.width = Math.round(rect.right - rect.left);
+        }
+        else
+        {
+            var position = this.getElementPosition(el);
+
+            result.top = position.top;
+            result.left = position.left;
+            result.height = el.offsetHeight;
+            result.width = el.offsetWidth;
+        }
+
+        return result;
+    },
+
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Measurement Methods
+
+    getMeasurement: function(el, name)
+    {
+        var result = {value: 0, unit: "px"};
+
+        var cssValue = this.getStyle(el, name);
+
+        if (!cssValue) return result;
+        if (cssValue.toLowerCase() == "auto") return result;
+
+        var reMeasure = /(\d+\.?\d*)(.*)/;
+        var m = cssValue.match(reMeasure);
+
+        if (m)
+        {
+            result.value = m[1]-0;
+            result.unit = m[2].toLowerCase();
+        }
+
+        return result;
+    },
+
+    getMeasurementInPixels: function(el, name)
+    {
+        if (!el) return null;
+
+        var m = this.getMeasurement(el, name);
+        var value = m.value;
+        var unit = m.unit;
+
+        if (unit == "px")
+            return value;
+
+        else if (unit == "pt")
+            return this.pointsToPixels(name, value);
+
+        else if (unit == "em")
+            return this.emToPixels(el, value);
+
+        else if (unit == "%")
+            return this.percentToPixels(el, value);
+
+        else if (unit == "ex")
+            return this.exToPixels(el, value);
+
+        // TODO: add other units. Maybe create a better general way
+        // to calculate measurements in different units.
+    },
+
+    getMeasurementBox1: function(el, name)
+    {
+        var sufixes = ["Top", "Left", "Bottom", "Right"];
+        var result = [];
+
+        for(var i=0, sufix; sufix=sufixes[i]; i++)
+            result[i] = Math.round(this.getMeasurementInPixels(el, name + sufix));
+
+        return {top:result[0], left:result[1], bottom:result[2], right:result[3]};
+    },
+
+    getMeasurementBox: function(el, name)
+    {
+        var result = [];
+        var sufixes = name == "border" ?
+                ["TopWidth", "LeftWidth", "BottomWidth", "RightWidth"] :
+                ["Top", "Left", "Bottom", "Right"];
+
+        if (isIE)
+        {
+            var propName, cssValue;
+            var autoMargin = null;
+
+            for(var i=0, sufix; sufix=sufixes[i]; i++)
+            {
+                propName = name + sufix;
+
+                cssValue = el.currentStyle[propName] || el.style[propName];
+
+                if (cssValue == "auto")
+                {
+                    if (!autoMargin)
+                        autoMargin = this.getCSSAutoMarginBox(el);
+
+                    result[i] = autoMargin[sufix.toLowerCase()];
+                }
+                else
+                    result[i] = this.getMeasurementInPixels(el, propName);
+
+            }
+
+        }
+        else
+        {
+            for(var i=0, sufix; sufix=sufixes[i]; i++)
+                result[i] = this.getMeasurementInPixels(el, name + sufix);
+        }
+
+        return {top:result[0], left:result[1], bottom:result[2], right:result[3]};
+    },
+
+    getCSSAutoMarginBox: function(el)
+    {
+        if (isIE && " meta title input script link a ".indexOf(" "+el.nodeName.toLowerCase()+" ") != -1)
+            return {top:0, left:0, bottom:0, right:0};
+            /**/
+
+        if (isIE && " h1 h2 h3 h4 h5 h6 h7 ul p ".indexOf(" "+el.nodeName.toLowerCase()+" ") == -1)
+            return {top:0, left:0, bottom:0, right:0};
+            /**/
+
+        var offsetTop = 0;
+        if (false && isIEStantandMode)
+        {
+            var scrollSize = Firebug.browser.getWindowScrollSize();
+            offsetTop = scrollSize.height;
+        }
+
+        var box = this.document.createElement("div");
+        //box.style.cssText = "margin:0; padding:1px; border: 0; position:static; overflow:hidden; visibility: hidden;";
+        box.style.cssText = "margin:0; padding:1px; border: 0; visibility: hidden;";
+
+        var clone = el.cloneNode(false);
+        var text = this.document.createTextNode("&nbsp;");
+        clone.appendChild(text);
+
+        box.appendChild(clone);
+
+        this.document.body.appendChild(box);
+
+        var marginTop = clone.offsetTop - box.offsetTop - 1;
+        var marginBottom = box.offsetHeight - clone.offsetHeight - 2 - marginTop;
+
+        var marginLeft = clone.offsetLeft - box.offsetLeft - 1;
+        var marginRight = box.offsetWidth - clone.offsetWidth - 2 - marginLeft;
+
+        this.document.body.removeChild(box);
+
+        return {top:marginTop+offsetTop, left:marginLeft, bottom:marginBottom-offsetTop, right:marginRight};
+    },
+
+    getFontSizeInPixels: function(el)
+    {
+        var size = this.getMeasurement(el, "fontSize");
+
+        if (size.unit == "px") return size.value;
+
+        // get font size, the dirty way
+        var computeDirtyFontSize = function(el, calibration)
+        {
+            var div = this.document.createElement("div");
+            var divStyle = offscreenStyle;
+
+            if (calibration)
+                divStyle +=  " font-size:"+calibration+"px;";
+
+            div.style.cssText = divStyle;
+            div.innerHTML = "A";
+            el.appendChild(div);
+
+            var value = div.offsetHeight;
+            el.removeChild(div);
+            return value;
+        };
+
+        /*
+        var calibrationBase = 200;
+        var calibrationValue = computeDirtyFontSize(el, calibrationBase);
+        var rate = calibrationBase / calibrationValue;
+        /**/
+
+        // the "dirty technique" fails in some environments, so we're using a static value
+        // based in some tests.
+        var rate = 200 / 225;
+
+        var value = computeDirtyFontSize(el);
+
+        return value * rate;
+    },
+
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Unit Funtions
+
+    pointsToPixels: function(name, value, returnFloat)
+    {
+        var axis = /Top$|Bottom$/.test(name) ? "y" : "x";
+
+        var result = value * pixelsPerInch[axis] / 72;
+
+        return returnFloat ? result : Math.round(result);
+    },
+
+    emToPixels: function(el, value)
+    {
+        if (!el) return null;
+
+        var fontSize = this.getFontSizeInPixels(el);
+
+        return Math.round(value * fontSize);
+    },
+
+    exToPixels: function(el, value)
+    {
+        if (!el) return null;
+
+        // get ex value, the dirty way
+        var div = this.document.createElement("div");
+        div.style.cssText = offscreenStyle + "width:"+value + "ex;";
+
+        el.appendChild(div);
+        var value = div.offsetWidth;
+        el.removeChild(div);
+
+        return value;
+    },
+
+    percentToPixels: function(el, value)
+    {
+        if (!el) return null;
+
+        // get % value, the dirty way
+        var div = this.document.createElement("div");
+        div.style.cssText = offscreenStyle + "width:"+value + "%;";
+
+        el.appendChild(div);
+        var value = div.offsetWidth;
+        el.removeChild(div);
+
+        return value;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getStyle: isIE ? function(el, name)
+    {
+        return el.currentStyle[name] || el.style[name] || undefined;
+    }
+    : function(el, name)
+    {
+        return this.document.defaultView.getComputedStyle(el,null)[name]
+            || el.style[name] || undefined;
+    }
+
+};
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns( /**@scope ns-chrome*/ function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Globals
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Window Options
+
+var WindowDefaultOptions =
+    {
+        type: "frame",
+        id: "FirebugUI"
+        //height: 350 // obsolete
+    },
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Instantiated objects
+
+    commandLine,
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Interface Elements Cache
+
+    fbTop,
+    fbContent,
+    fbContentStyle,
+    fbBottom,
+    fbBtnInspect,
+
+    fbToolbar,
+
+    fbPanelBox1,
+    fbPanelBox1Style,
+    fbPanelBox2,
+    fbPanelBox2Style,
+    fbPanelBar2Box,
+    fbPanelBar2BoxStyle,
+
+    fbHSplitter,
+    fbVSplitter,
+    fbVSplitterStyle,
+
+    fbPanel1,
+    fbPanel1Style,
+    fbPanel2,
+    fbPanel2Style,
+
+    fbConsole,
+    fbConsoleStyle,
+    fbHTML,
+
+    fbCommandLine,
+    fbLargeCommandLine,
+    fbLargeCommandButtons,
+
+//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Cached size values
+
+    topHeight,
+    topPartialHeight,
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    chromeRedrawSkipRate = isIE ? 75 : isOpera ? 80 : 75,
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    lastSelectedPanelName,
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    focusCommandLineState = 0,
+    lastFocusedPanelName,
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    lastHSplitterMouseMove = 0,
+    onHSplitterMouseMoveBuffer = null,
+    onHSplitterMouseMoveTimer = null,
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    lastVSplitterMouseMove = 0;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+
+// ************************************************************************************************
+// FirebugChrome
+
+FBL.defaultPersistedState =
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    isOpen: false,
+    height: 300,
+    sidePanelWidth: 350,
+
+    selectedPanelName: "Console",
+    selectedHTMLElementId: null,
+
+    htmlSelectionStack: []
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+};
+
+/**@namespace*/
+FBL.FirebugChrome =
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    //isOpen: false,
+    //height: 300,
+    //sidePanelWidth: 350,
+
+    //selectedPanelName: "Console",
+    //selectedHTMLElementId: null,
+
+    chromeMap: {},
+
+    htmlSelectionStack: [],
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    create: function()
+    {
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.create", "creating chrome window");
+
+        createChromeWindow();
+    },
+
+    initialize: function()
+    {
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("FirebugChrome.initialize", "initializing chrome window");
+
+        if (Env.chrome.type == "frame" || Env.chrome.type == "div")
+            ChromeMini.create(Env.chrome);
+
+        var chrome = Firebug.chrome = new Chrome(Env.chrome);
+        FirebugChrome.chromeMap[chrome.type] = chrome;
+
+        addGlobalEvent("keydown", onGlobalKeyDown);
+
+        if (Env.Options.enablePersistent && chrome.type == "popup")
+        {
+            // TODO: xxxpedro persist - revise chrome synchronization when in persistent mode
+            var frame = FirebugChrome.chromeMap.frame;
+            if (frame)
+                frame.close();
+
+            //chrome.reattach(frame, chrome);
+            //TODO: xxxpedro persist synchronize?
+            chrome.initialize();
+        }
+    },
+
+    clone: function(FBChrome)
+    {
+        for (var name in FBChrome)
+        {
+            var prop = FBChrome[name];
+            if (FBChrome.hasOwnProperty(name) && !isFunction(prop))
+            {
+                this[name] = prop;
+            }
+        }
+    }
+};
+
+
+
+// ************************************************************************************************
+// Chrome Window Creation
+
+var createChromeWindow = function(options)
+{
+    options = extend(WindowDefaultOptions, options || {});
+
+    //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Locals
+
+    var browserWin = Env.browser.window;
+    var browserContext = new Context(browserWin);
+    var prefs = Store.get("FirebugLite");
+    var persistedState = prefs && prefs.persistedState || defaultPersistedState;
+
+    var chrome = {},
+
+        context = options.context || Env.browser,
+
+        type = chrome.type = Env.Options.enablePersistent ?
+                "popup" :
+                options.type,
+
+        isChromeFrame = type == "frame",
+
+        useLocalSkin = Env.useLocalSkin,
+
+        url = useLocalSkin ?
+                Env.Location.skin :
+                "about:blank",
+
+        // document.body not available in XML+XSL documents in Firefox
+        body = context.document.getElementsByTagName("body")[0],
+
+        formatNode = function(node)
+        {
+            if (!Env.isDebugMode)
+            {
+                node.firebugIgnore = true;
+            }
+
+            var browserWinSize = browserContext.getWindowSize();
+            var height = persistedState.height || 300;
+
+            height = Math.min(browserWinSize.height, height);
+            height = Math.max(200, height);
+
+            node.style.border = "0";
+            node.style.visibility = "hidden";
+            node.style.zIndex = "2147483647"; // MAX z-index = 2147483647
+            node.style.position = noFixedPosition ? "absolute" : "fixed";
+            node.style.width = "100%"; // "102%"; IE auto margin bug
+            node.style.left = "0";
+            node.style.bottom = noFixedPosition ? "-1px" : "0";
+            node.style.height = height + "px";
+
+            // avoid flickering during chrome rendering
+            //if (isFirefox)
+            //    node.style.display = "none";
+        },
+
+        createChromeDiv = function()
+        {
+            //Firebug.Console.warn("Firebug Lite GUI is working in 'windowless mode'. It may behave slower and receive interferences from the page in which it is installed.");
+
+            var node = chrome.node = createGlobalElement("div"),
+                style = createGlobalElement("style"),
+
+                css = FirebugChrome.Skin.CSS
+                        /*
+                        .replace(/;/g, " !important;")
+                        .replace(/!important\s!important/g, "!important")
+                        .replace(/display\s*:\s*(\w+)\s*!important;/g, "display:$1;")*/,
+
+                        // reset some styles to minimize interference from the main page's style
+                rules = ".fbBody *{margin:0;padding:0;font-size:11px;line-height:13px;color:inherit;}" +
+                        // load the chrome styles
+                        css +
+                        // adjust some remaining styles
+                        ".fbBody #fbHSplitter{position:absolute !important;} .fbBody #fbHTML span{line-height:14px;} .fbBody .lineNo div{line-height:inherit !important;}";
+            /*
+            if (isIE)
+            {
+                // IE7 CSS bug (FbChrome table bigger than its parent div)
+                rules += ".fbBody table.fbChrome{position: static !important;}";
+            }/**/
+
+            style.type = "text/css";
+
+            if (style.styleSheet)
+                style.styleSheet.cssText = rules;
+            else
+                style.appendChild(context.document.createTextNode(rules));
+
+            document.getElementsByTagName("head")[0].appendChild(style);
+
+            node.className = "fbBody";
+            node.style.overflow = "hidden";
+            node.innerHTML = getChromeDivTemplate();
+
+            if (isIE)
+            {
+                // IE7 CSS bug (FbChrome table bigger than its parent div)
+                setTimeout(function(){
+                node.firstChild.style.height = "1px";
+                node.firstChild.style.position = "static";
+                },0);
+                /**/
+            }
+
+            formatNode(node);
+
+            body.appendChild(node);
+
+            chrome.window = window;
+            chrome.document = document;
+            onChromeLoad(chrome);
+        };
+
+    //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    try
+    {
+        //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // create the Chrome as a "div" (windowless mode)
+        if (type == "div")
+        {
+            createChromeDiv();
+            return;
+        }
+
+        //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // cretate the Chrome as an "iframe"
+        else if (isChromeFrame)
+        {
+            // Create the Chrome Frame
+            var node = chrome.node = createGlobalElement("iframe");
+            node.setAttribute("src", url);
+            node.setAttribute("frameBorder", "0");
+
+            formatNode(node);
+
+            body.appendChild(node);
+
+            // must set the id after appending to the document, otherwise will cause an
+            // strange error in IE, making the iframe load the page in which the bookmarklet
+            // was created (like getfirebug.com), before loading the injected UI HTML,
+            // generating an "Access Denied" error.
+            node.id = options.id;
+        }
+
+        //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // create the Chrome as a "popup"
+        else
+        {
+            var height = persistedState.popupHeight || 300;
+            var browserWinSize = browserContext.getWindowSize();
+
+            var browserWinLeft = typeof browserWin.screenX == "number" ?
+                    browserWin.screenX : browserWin.screenLeft;
+
+            var popupLeft = typeof persistedState.popupLeft == "number" ?
+                    persistedState.popupLeft : browserWinLeft;
+
+            var browserWinTop = typeof browserWin.screenY == "number" ?
+                    browserWin.screenY : browserWin.screenTop;
+
+            var popupTop = typeof persistedState.popupTop == "number" ?
+                    persistedState.popupTop :
+                    Math.max(
+                            0,
+                            Math.min(
+                                    browserWinTop + browserWinSize.height - height,
+                                    // Google Chrome bug
+                                    screen.availHeight - height - 61
+                                )
+                            );
+
+            var popupWidth = typeof persistedState.popupWidth == "number" ?
+                    persistedState.popupWidth :
+                    Math.max(
+                            0,
+                            Math.min(
+                                    browserWinSize.width,
+                                    // Opera opens popup in a new tab if it's too big!
+                                    screen.availWidth-10
+                                )
+                            );
+
+            var popupHeight = typeof persistedState.popupHeight == "number" ?
+                    persistedState.popupHeight : 300;
+
+            var options = [
+                    "true,top=", popupTop,
+                    ",left=", popupLeft,
+                    ",height=", popupHeight,
+                    ",width=", popupWidth,
+                    ",resizable"
+                ].join(""),
+
+                node = chrome.node = context.window.open(
+                    url,
+                    "popup",
+                    options
+                );
+
+            if (node)
+            {
+                try
+                {
+                    node.focus();
+                }
+                catch(E)
+                {
+                    alert("Firebug Error: Firebug popup was blocked.");
+                    return;
+                }
+            }
+            else
+            {
+                alert("Firebug Error: Firebug popup was blocked.");
+                return;
+            }
+        }
+
+        //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // Inject the interface HTML if it is not using the local skin
+
+        if (!useLocalSkin)
+        {
+            var tpl = getChromeTemplate(!isChromeFrame),
+                doc = isChromeFrame ? node.contentWindow.document : node.document;
+
+            doc.write(tpl);
+            doc.close();
+        }
+
+        //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // Wait the Window to be loaded
+
+        var win,
+
+            waitDelay = useLocalSkin ? isChromeFrame ? 200 : 300 : 100,
+
+            waitForWindow = function()
+            {
+                if ( // Frame loaded... OR
+                     isChromeFrame && (win=node.contentWindow) &&
+                     node.contentWindow.document.getElementById("fbCommandLine") ||
+
+                     // Popup loaded
+                     !isChromeFrame && (win=node.window) && node.document &&
+                     node.document.getElementById("fbCommandLine") )
+                {
+                    chrome.window = win.window;
+                    chrome.document = win.document;
+
+                    // Prevent getting the wrong chrome height in FF when opening a popup
+                    setTimeout(function(){
+                        onChromeLoad(chrome);
+                    }, useLocalSkin ? 200 : 0);
+                }
+                else
+                    setTimeout(waitForWindow, waitDelay);
+            };
+
+        waitForWindow();
+    }
+    catch(e)
+    {
+        var msg = e.message || e;
+
+        if (/access/i.test(msg))
+        {
+            // Firebug Lite could not create a window for its Graphical User Interface due to
+            // a access restriction. This happens in some pages, when loading via bookmarklet.
+            // In such cases, the only way is to load the GUI in a "windowless mode".
+
+            if (isChromeFrame)
+                body.removeChild(node);
+            else if(type == "popup")
+                node.close();
+
+            // Load the GUI in a "windowless mode"
+            createChromeDiv();
+        }
+        else
+        {
+            alert("Firebug Error: Firebug GUI could not be created.");
+        }
+    }
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var onChromeLoad = function onChromeLoad(chrome)
+{
+    Env.chrome = chrome;
+
+    if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Chrome onChromeLoad", "chrome window loaded");
+
+    if (Env.Options.enablePersistent)
+    {
+        // TODO: xxxpedro persist - make better chrome synchronization when in persistent mode
+        Env.FirebugChrome = FirebugChrome;
+
+        chrome.window.Firebug = chrome.window.Firebug || {};
+        chrome.window.Firebug.SharedEnv = Env;
+
+        if (Env.isDevelopmentMode)
+        {
+            Env.browser.window.FBDev.loadChromeApplication(chrome);
+        }
+        else
+        {
+            var doc = chrome.document;
+            var script = doc.createElement("script");
+            script.src = Env.Location.app + "#remote,persist";
+            doc.getElementsByTagName("head")[0].appendChild(script);
+        }
+    }
+    else
+    {
+        if (chrome.type == "frame" || chrome.type == "div")
+        {
+            // initialize the chrome application
+            setTimeout(function(){
+                FBL.Firebug.initialize();
+            },0);
+        }
+        else if (chrome.type == "popup")
+        {
+            var oldChrome = FirebugChrome.chromeMap.frame;
+
+            var newChrome = new Chrome(chrome);
+
+            // TODO: xxxpedro sync detach reattach attach
+            dispatch(newChrome.panelMap, "detach", [oldChrome, newChrome]);
+
+            newChrome.reattach(oldChrome, newChrome);
+        }
+    }
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var getChromeDivTemplate = function()
+{
+    return FirebugChrome.Skin.HTML;
+};
+
+var getChromeTemplate = function(isPopup)
+{
+    var tpl = FirebugChrome.Skin;
+    var r = [], i = -1;
+
+    r[++i] = '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/DTD/strict.dtd">';
+    r[++i] = '<html><head><title>';
+    r[++i] = Firebug.version;
+
+    /*
+    r[++i] = '</title><link href="';
+    r[++i] = Env.Location.skinDir + 'firebug.css';
+    r[++i] = '" rel="stylesheet" type="text/css" />';
+    /**/
+
+    r[++i] = '</title><style>html,body{margin:0;padding:0;overflow:hidden;}';
+    r[++i] = tpl.CSS;
+    r[++i] = '</style>';
+    /**/
+
+    r[++i] = '</head><body class="fbBody' + (isPopup ? ' FirebugPopup' : '') + '">';
+    r[++i] = tpl.HTML;
+    r[++i] = '</body></html>';
+
+    return r.join("");
+};
+
+
+// ************************************************************************************************
+// Chrome Class
+
+/**@class*/
+var Chrome = function Chrome(chrome)
+{
+    var type = chrome.type;
+    var Base = type == "frame" || type == "div" ? ChromeFrameBase : ChromePopupBase;
+
+    append(this, Base);   // inherit from base class (ChromeFrameBase or ChromePopupBase)
+    append(this, chrome); // inherit chrome window properties
+    append(this, new Context(chrome.window)); // inherit from Context class
+
+    FirebugChrome.chromeMap[type] = this;
+    Firebug.chrome = this;
+    Env.chrome = chrome.window;
+
+    this.commandLineVisible = false;
+    this.sidePanelVisible = false;
+
+    this.create();
+
+    return this;
+};
+
+// ************************************************************************************************
+// ChromeBase
+
+/**
+ * @namespace
+ * @extends FBL.Controller
+ * @extends FBL.PanelBar
+ **/
+var ChromeBase = {};
+append(ChromeBase, Controller);
+append(ChromeBase, PanelBar);
+append(ChromeBase,
+/**@extend ns-chrome-ChromeBase*/
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // inherited properties
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // inherited from createChrome function
+
+    node: null,
+    type: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // inherited from Context.prototype
+
+    document: null,
+    window: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // value properties
+
+    sidePanelVisible: false,
+    commandLineVisible: false,
+    largeCommandLineVisible: false,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // object properties
+
+    inspectButton: null,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    create: function()
+    {
+        PanelBar.create.call(this);
+
+        if (Firebug.Inspector)
+            this.inspectButton = new Button({
+                type: "toggle",
+                element: $("fbChrome_btInspect"),
+                owner: Firebug.Inspector,
+
+                onPress: Firebug.Inspector.startInspecting,
+                onUnpress: Firebug.Inspector.stopInspecting
+            });
+    },
+
+    destroy: function()
+    {
+        if(Firebug.Inspector)
+            this.inspectButton.destroy();
+
+        PanelBar.destroy.call(this);
+
+        this.shutdown();
+    },
+
+    testMenu: function()
+    {
+        var firebugMenu = new Menu(
+        {
+            id: "fbFirebugMenu",
+
+            items:
+            [
+                {
+                    label: "Open Firebug",
+                    type: "shortcut",
+                    key: isFirefox ? "Shift+F12" : "F12",
+                    checked: true,
+                    command: "toggleChrome"
+                },
+                {
+                    label: "Open Firebug in New Window",
+                    type: "shortcut",
+                    key: isFirefox ? "Ctrl+Shift+F12" : "Ctrl+F12",
+                    command: "openPopup"
+                },
+                {
+                    label: "Inspect Element",
+                    type: "shortcut",
+                    key: "Ctrl+Shift+C",
+                    command: "toggleInspect"
+                },
+                {
+                    label: "Command Line",
+                    type: "shortcut",
+                    key: "Ctrl+Shift+L",
+                    command: "focusCommandLine"
+                },
+                "-",
+                {
+                    label: "Options",
+                    type: "group",
+                    child: "fbFirebugOptionsMenu"
+                },
+                "-",
+                {
+                    label: "Firebug Lite Website...",
+                    command: "visitWebsite"
+                },
+                {
+                    label: "Discussion Group...",
+                    command: "visitDiscussionGroup"
+                },
+                {
+                    label: "Issue Tracker...",
+                    command: "visitIssueTracker"
+                }
+            ],
+
+            onHide: function()
+            {
+                iconButton.restore();
+            },
+
+            toggleChrome: function()
+            {
+                Firebug.chrome.toggle();
+            },
+
+            openPopup: function()
+            {
+                Firebug.chrome.toggle(true, true);
+            },
+
+            toggleInspect: function()
+            {
+                Firebug.Inspector.toggleInspect();
+            },
+
+            focusCommandLine: function()
+            {
+                Firebug.chrome.focusCommandLine();
+            },
+
+            visitWebsite: function()
+            {
+                this.visit("http://getfirebug.com/lite.html");
+            },
+
+            visitDiscussionGroup: function()
+            {
+                this.visit("http://groups.google.com/group/firebug");
+            },
+
+            visitIssueTracker: function()
+            {
+                this.visit("http://code.google.com/p/fbug/issues/list");
+            },
+
+            visit: function(url)
+            {
+                window.open(url);
+            }
+
+        });
+
+        /**@private*/
+        var firebugOptionsMenu =
+        {
+            id: "fbFirebugOptionsMenu",
+
+            getItems: function()
+            {
+                var cookiesDisabled = !Firebug.saveCookies;
+
+                return [
+                    {
+                        label: "Start Opened",
+                        type: "checkbox",
+                        value: "startOpened",
+                        checked: Firebug.startOpened,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Start in New Window",
+                        type: "checkbox",
+                        value: "startInNewWindow",
+                        checked: Firebug.startInNewWindow,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Show Icon When Hidden",
+                        type: "checkbox",
+                        value: "showIconWhenHidden",
+                        checked: Firebug.showIconWhenHidden,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Override Console Object",
+                        type: "checkbox",
+                        value: "overrideConsole",
+                        checked: Firebug.overrideConsole,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Ignore Firebug Elements",
+                        type: "checkbox",
+                        value: "ignoreFirebugElements",
+                        checked: Firebug.ignoreFirebugElements,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Disable When Firebug Active",
+                        type: "checkbox",
+                        value: "disableWhenFirebugActive",
+                        checked: Firebug.disableWhenFirebugActive,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Disable XHR Listener",
+                        type: "checkbox",
+                        value: "disableXHRListener",
+                        checked: Firebug.disableXHRListener,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Disable Resource Fetching",
+                        type: "checkbox",
+                        value: "disableResourceFetching",
+                        checked: Firebug.disableResourceFetching,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Enable Trace Mode",
+                        type: "checkbox",
+                        value: "enableTrace",
+                        checked: Firebug.enableTrace,
+                        disabled: cookiesDisabled
+                    },
+                    {
+                        label: "Enable Persistent Mode (experimental)",
+                        type: "checkbox",
+                        value: "enablePersistent",
+                        checked: Firebug.enablePersistent,
+                        disabled: cookiesDisabled
+                    },
+                    "-",
+                    {
+                        label: "Reset All Firebug Options",
+                        command: "restorePrefs",
+                        disabled: cookiesDisabled
+                    }
+                ];
+            },
+
+            onCheck: function(target, value, checked)
+            {
+                Firebug.setPref(value, checked);
+            },
+
+            restorePrefs: function(target)
+            {
+                Firebug.erasePrefs();
+
+                if (target)
+                    this.updateMenu(target);
+            },
+
+            updateMenu: function(target)
+            {
+                var options = getElementsByClass(target.parentNode, "fbMenuOption");
+
+                var firstOption = options[0];
+                var enabled = Firebug.saveCookies;
+                if (enabled)
+                    Menu.check(firstOption);
+                else
+                    Menu.uncheck(firstOption);
+
+                if (enabled)
+                    Menu.check(options[0]);
+                else
+                    Menu.uncheck(options[0]);
+
+                for (var i = 1, length = options.length; i < length; i++)
+                {
+                    var option = options[i];
+
+                    var value = option.getAttribute("value");
+                    var pref = Firebug[value];
+
+                    if (pref)
+                        Menu.check(option);
+                    else
+                        Menu.uncheck(option);
+
+                    if (enabled)
+                        Menu.enable(option);
+                    else
+                        Menu.disable(option);
+                }
+            }
+        };
+
+        Menu.register(firebugOptionsMenu);
+
+        var menu = firebugMenu;
+
+        var testMenuClick = function(event)
+        {
+            //console.log("testMenuClick");
+            cancelEvent(event, true);
+
+            var target = event.target || event.srcElement;
+
+            if (menu.isVisible)
+                menu.hide();
+            else
+            {
+                var offsetLeft = isIE6 ? 1 : -4,  // IE6 problem with fixed position
+
+                    chrome = Firebug.chrome,
+
+                    box = chrome.getElementBox(target),
+
+                    offset = chrome.type == "div" ?
+                            chrome.getElementPosition(chrome.node) :
+                            {top: 0, left: 0};
+
+                menu.show(
+                            box.left + offsetLeft - offset.left,
+                            box.top + box.height -5 - offset.top
+                        );
+            }
+
+            return false;
+        };
+
+        var iconButton = new IconButton({
+            type: "toggle",
+            element: $("fbFirebugButton"),
+
+            onClick: testMenuClick
+        });
+
+        iconButton.initialize();
+
+        //addEvent($("fbToolbarIcon"), "click", testMenuClick);
+    },
+
+    initialize: function()
+    {
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        if (Env.bookmarkletOutdated)
+            Firebug.Console.logFormatted([
+                  "A new bookmarklet version is available. " +
+                  "Please visit http://getfirebug.com/firebuglite#Install and update it."
+                ], Firebug.context, "warn");
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        if (Firebug.Console)
+            Firebug.Console.flush();
+
+        if (Firebug.Trace)
+            FBTrace.flush(Firebug.Trace);
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.chrome.initialize", "initializing chrome application");
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // initialize inherited classes
+        Controller.initialize.call(this);
+        PanelBar.initialize.call(this);
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // create the interface elements cache
+
+        fbTop = $("fbTop");
+        fbContent = $("fbContent");
+        fbContentStyle = fbContent.style;
+        fbBottom = $("fbBottom");
+        fbBtnInspect = $("fbBtnInspect");
+
+        fbToolbar = $("fbToolbar");
+
+        fbPanelBox1 = $("fbPanelBox1");
+        fbPanelBox1Style = fbPanelBox1.style;
+        fbPanelBox2 = $("fbPanelBox2");
+        fbPanelBox2Style = fbPanelBox2.style;
+        fbPanelBar2Box = $("fbPanelBar2Box");
+        fbPanelBar2BoxStyle = fbPanelBar2Box.style;
+
+        fbHSplitter = $("fbHSplitter");
+        fbVSplitter = $("fbVSplitter");
+        fbVSplitterStyle = fbVSplitter.style;
+
+        fbPanel1 = $("fbPanel1");
+        fbPanel1Style = fbPanel1.style;
+        fbPanel2 = $("fbPanel2");
+        fbPanel2Style = fbPanel2.style;
+
+        fbConsole = $("fbConsole");
+        fbConsoleStyle = fbConsole.style;
+        fbHTML = $("fbHTML");
+
+        fbCommandLine = $("fbCommandLine");
+        fbLargeCommandLine = $("fbLargeCommandLine");
+        fbLargeCommandButtons = $("fbLargeCommandButtons");
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // static values cache
+        topHeight = fbTop.offsetHeight;
+        topPartialHeight = fbToolbar.offsetHeight;
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+        disableTextSelection($("fbToolbar"));
+        disableTextSelection($("fbPanelBarBox"));
+        disableTextSelection($("fbPanelBar1"));
+        disableTextSelection($("fbPanelBar2"));
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // Add the "javascript:void(0)" href attributes used to make the hover effect in IE6
+        if (isIE6 && Firebug.Selector)
+        {
+            // TODO: xxxpedro change to getElementsByClass
+            var as = $$(".fbHover");
+            for (var i=0, a; a=as[i]; i++)
+            {
+                a.setAttribute("href", "javascript:void(0)");
+            }
+        }
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // initialize all panels
+        /*
+        var panelMap = Firebug.panelTypes;
+        for (var i=0, p; p=panelMap[i]; i++)
+        {
+            if (!p.parentPanel)
+            {
+                this.addPanel(p.prototype.name);
+            }
+        }
+        /**/
+
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+
+        if(Firebug.Inspector)
+            this.inspectButton.initialize();
+
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+
+        this.addController(
+            [$("fbLargeCommandLineIcon"), "click", this.showLargeCommandLine]
+        );
+
+        // ************************************************************************************************
+
+        // Select the first registered panel
+        // TODO: BUG IE7
+        var self = this;
+        setTimeout(function(){
+            self.selectPanel(Firebug.context.persistedState.selectedPanelName);
+
+            if (Firebug.context.persistedState.selectedPanelName == "Console" && Firebug.CommandLine)
+                Firebug.chrome.focusCommandLine();
+        },0);
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        //this.draw();
+
+
+
+
+
+
+
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+        var onPanelMouseDown = function onPanelMouseDown(event)
+        {
+            //console.log("onPanelMouseDown", event.target || event.srcElement, event);
+
+            var target = event.target || event.srcElement;
+
+            if (FBL.isLeftClick(event))
+            {
+                var editable = FBL.getAncestorByClass(target, "editable");
+
+                // if an editable element has been clicked then start editing
+                if (editable)
+                {
+                    Firebug.Editor.startEditing(editable);
+                    FBL.cancelEvent(event);
+                }
+                // if any other element has been clicked then stop editing
+                else
+                {
+                    if (!hasClass(target, "textEditorInner"))
+                        Firebug.Editor.stopEditing();
+                }
+            }
+            else if (FBL.isMiddleClick(event) && Firebug.getRepNode(target))
+            {
+                // Prevent auto-scroll when middle-clicking a rep object
+                FBL.cancelEvent(event);
+            }
+        };
+
+        Firebug.getElementPanel = function(element)
+        {
+            var panelNode = getAncestorByClass(element, "fbPanel");
+            var id = panelNode.id.substr(2);
+
+            var panel = Firebug.chrome.panelMap[id];
+
+            if (!panel)
+            {
+                if (Firebug.chrome.selectedPanel.sidePanelBar)
+                    panel = Firebug.chrome.selectedPanel.sidePanelBar.panelMap[id];
+            }
+
+            return panel;
+        };
+
+
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+        // TODO: xxxpedro port to Firebug
+
+        // Improved window key code event listener. Only one "keydown" event will be attached
+        // to the window, and the onKeyCodeListen() function will delegate which listeners
+        // should be called according to the event.keyCode fired.
+        var onKeyCodeListenersMap = [];
+        var onKeyCodeListen = function(event)
+        {
+            for (var keyCode in onKeyCodeListenersMap)
+            {
+                var listeners = onKeyCodeListenersMap[keyCode];
+
+                for (var i = 0, listener; listener = listeners[i]; i++)
+                {
+                    var filter = listener.filter || FBL.noKeyModifiers;
+
+                    if (event.keyCode == keyCode && (!filter || filter(event)))
+                    {
+                        listener.listener();
+                        FBL.cancelEvent(event, true);
+                        return false;
+                    }
+                }
+            }
+        };
+
+        addEvent(Firebug.chrome.document, "keydown", onKeyCodeListen);
+
+        /**
+         * @name keyCodeListen
+         * @memberOf FBL.FirebugChrome
+         */
+        Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
+        {
+            var keyCode = KeyEvent["DOM_VK_"+key];
+
+            if (!onKeyCodeListenersMap[keyCode])
+                onKeyCodeListenersMap[keyCode] = [];
+
+            onKeyCodeListenersMap[keyCode].push({
+                filter: filter,
+                listener: listener
+            });
+
+            return keyCode;
+        };
+
+        /**
+         * @name keyIgnore
+         * @memberOf FBL.FirebugChrome
+         */
+        Firebug.chrome.keyIgnore = function(keyCode)
+        {
+            onKeyCodeListenersMap[keyCode] = null;
+            delete onKeyCodeListenersMap[keyCode];
+        };
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+        /**/
+        // move to shutdown
+        //removeEvent(Firebug.chrome.document, "keydown", listener[0]);
+
+
+        /*
+        Firebug.chrome.keyCodeListen = function(key, filter, listener, capture)
+        {
+            if (!filter)
+                filter = FBL.noKeyModifiers;
+
+            var keyCode = KeyEvent["DOM_VK_"+key];
+
+            var fn = function fn(event)
+            {
+                if (event.keyCode == keyCode && (!filter || filter(event)))
+                {
+                    listener();
+                    FBL.cancelEvent(event, true);
+                    return false;
+                }
+            }
+
+            addEvent(Firebug.chrome.document, "keydown", fn);
+
+            return [fn, capture];
+        };
+
+        Firebug.chrome.keyIgnore = function(listener)
+        {
+            removeEvent(Firebug.chrome.document, "keydown", listener[0]);
+        };
+        /**/
+
+
+        this.addController(
+                [fbPanel1, "mousedown", onPanelMouseDown],
+                [fbPanel2, "mousedown", onPanelMouseDown]
+             );
+/**/
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+
+        // menus can be used without domplate
+        if (FBL.domplate)
+            this.testMenu();
+        /**/
+
+        //test XHR
+        /*
+        setTimeout(function(){
+
+        FBL.Ajax.request({url: "../content/firebug/boot.js"});
+        FBL.Ajax.request({url: "../content/firebug/boot.js.invalid"});
+
+        },1000);
+        /**/
+    },
+
+    shutdown: function()
+    {
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+
+        if(Firebug.Inspector)
+            this.inspectButton.shutdown();
+
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+        // ************************************************************************************************
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+        // remove disableTextSelection event handlers
+        restoreTextSelection($("fbToolbar"));
+        restoreTextSelection($("fbPanelBarBox"));
+        restoreTextSelection($("fbPanelBar1"));
+        restoreTextSelection($("fbPanelBar2"));
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // shutdown inherited classes
+        Controller.shutdown.call(this);
+        PanelBar.shutdown.call(this);
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // Remove the interface elements cache (this must happen after calling
+        // the shutdown method of all dependent components to avoid errors)
+
+        fbTop = null;
+        fbContent = null;
+        fbContentStyle = null;
+        fbBottom = null;
+        fbBtnInspect = null;
+
+        fbToolbar = null;
+
+        fbPanelBox1 = null;
+        fbPanelBox1Style = null;
+        fbPanelBox2 = null;
+        fbPanelBox2Style = null;
+        fbPanelBar2Box = null;
+        fbPanelBar2BoxStyle = null;
+
+        fbHSplitter = null;
+        fbVSplitter = null;
+        fbVSplitterStyle = null;
+
+        fbPanel1 = null;
+        fbPanel1Style = null;
+        fbPanel2 = null;
+
+        fbConsole = null;
+        fbConsoleStyle = null;
+        fbHTML = null;
+
+        fbCommandLine = null;
+        fbLargeCommandLine = null;
+        fbLargeCommandButtons = null;
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // static values cache
+
+        topHeight = null;
+        topPartialHeight = null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    toggle: function(forceOpen, popup)
+    {
+        if(popup)
+        {
+            this.detach();
+        }
+        else
+        {
+            if (isOpera && Firebug.chrome.type == "popup" && Firebug.chrome.node.closed)
+            {
+                var frame = FirebugChrome.chromeMap.frame;
+                frame.reattach();
+
+                FirebugChrome.chromeMap.popup = null;
+
+                frame.open();
+
+                return;
+            }
+
+            // If the context is a popup, ignores the toggle process
+            if (Firebug.chrome.type == "popup") return;
+
+            var shouldOpen = forceOpen || !Firebug.context.persistedState.isOpen;
+
+            if(shouldOpen)
+               this.open();
+            else
+               this.close();
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    detach: function()
+    {
+        if(!FirebugChrome.chromeMap.popup)
+        {
+            this.close();
+            createChromeWindow({type: "popup"});
+        }
+    },
+
+    reattach: function(oldChrome, newChrome)
+    {
+        Firebug.browser.window.Firebug = Firebug;
+
+        // chrome synchronization
+        var newPanelMap = newChrome.panelMap;
+        var oldPanelMap = oldChrome.panelMap;
+
+        var panel;
+        for(var name in newPanelMap)
+        {
+            // TODO: xxxpedro innerHTML
+            panel = newPanelMap[name];
+            if (panel.options.innerHTMLSync)
+                panel.panelNode.innerHTML = oldPanelMap[name].panelNode.innerHTML;
+        }
+
+        Firebug.chrome = newChrome;
+
+        // TODO: xxxpedro sync detach reattach attach
+        //dispatch(Firebug.chrome.panelMap, "detach", [oldChrome, newChrome]);
+
+        if (newChrome.type == "popup")
+        {
+            newChrome.initialize();
+            //dispatch(Firebug.modules, "initialize", []);
+        }
+        else
+        {
+            // TODO: xxxpedro only needed in persistent
+            // should use FirebugChrome.clone, but popup FBChrome
+            // isn't acessible
+            Firebug.context.persistedState.selectedPanelName = oldChrome.selectedPanel.name;
+        }
+
+        dispatch(newPanelMap, "reattach", [oldChrome, newChrome]);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    draw: function()
+    {
+        var size = this.getSize();
+
+        // Height related values
+        var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0,
+
+            y = Math.max(size.height /* chrome height */, topHeight),
+
+            heightValue = Math.max(y - topHeight - commandLineHeight /* fixed height */, 0),
+
+            height = heightValue + "px",
+
+            // Width related values
+            sideWidthValue = Firebug.chrome.sidePanelVisible ? Firebug.context.persistedState.sidePanelWidth : 0,
+
+            width = Math.max(size.width /* chrome width */ - sideWidthValue, 0) + "px";
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // Height related rendering
+        fbPanelBox1Style.height = height;
+        fbPanel1Style.height = height;
+
+        if (isIE || isOpera)
+        {
+            // Fix IE and Opera problems with auto resizing the verticall splitter
+            fbVSplitterStyle.height = Math.max(y - topPartialHeight - commandLineHeight, 0) + "px";
+        }
+        //xxxpedro FF2 only?
+        /*
+        else if (isFirefox)
+        {
+            // Fix Firefox problem with table rows with 100% height (fit height)
+            fbContentStyle.maxHeight = Math.max(y - fixedHeight, 0)+ "px";
+        }/**/
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // Width related rendering
+        fbPanelBox1Style.width = width;
+        fbPanel1Style.width = width;
+
+        // SidePanel rendering
+        if (Firebug.chrome.sidePanelVisible)
+        {
+            sideWidthValue = Math.max(sideWidthValue - 6, 0);
+
+            var sideWidth = sideWidthValue + "px";
+
+            fbPanelBox2Style.width = sideWidth;
+
+            fbVSplitterStyle.right = sideWidth;
+
+            if (Firebug.chrome.largeCommandLineVisible)
+            {
+                fbLargeCommandLine = $("fbLargeCommandLine");
+
+                fbLargeCommandLine.style.height = heightValue - 4 + "px";
+                fbLargeCommandLine.style.width = sideWidthValue - 2 + "px";
+
+                fbLargeCommandButtons = $("fbLargeCommandButtons");
+                fbLargeCommandButtons.style.width = sideWidth;
+            }
+            else
+            {
+                fbPanel2Style.height = height;
+                fbPanel2Style.width = sideWidth;
+
+                fbPanelBar2BoxStyle.width = sideWidth;
+            }
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getSize: function()
+    {
+        return this.type == "div" ?
+            {
+                height: this.node.offsetHeight,
+                width: this.node.offsetWidth
+            }
+            :
+            this.getWindowSize();
+    },
+
+    resize: function()
+    {
+        var self = this;
+
+        // avoid partial resize when maximizing window
+        setTimeout(function(){
+            self.draw();
+
+            if (noFixedPosition && (self.type == "frame" || self.type == "div"))
+                self.fixIEPosition();
+        }, 0);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    layout: function(panel)
+    {
+        if (FBTrace.DBG_CHROME) FBTrace.sysout("Chrome.layout", "");
+
+        var options = panel.options;
+
+        changeCommandLineVisibility(options.hasCommandLine);
+        changeSidePanelVisibility(panel.hasSidePanel);
+
+        Firebug.chrome.draw();
+    },
+
+    showLargeCommandLine: function(hideToggleIcon)
+    {
+        var chrome = Firebug.chrome;
+
+        if (!chrome.largeCommandLineVisible)
+        {
+            chrome.largeCommandLineVisible = true;
+
+            if (chrome.selectedPanel.options.hasCommandLine)
+            {
+                if (Firebug.CommandLine)
+                    Firebug.CommandLine.blur();
+
+                changeCommandLineVisibility(false);
+            }
+
+            changeSidePanelVisibility(true);
+
+            fbLargeCommandLine.style.display = "block";
+            fbLargeCommandButtons.style.display = "block";
+
+            fbPanel2Style.display = "none";
+            fbPanelBar2BoxStyle.display = "none";
+
+            chrome.draw();
+
+            fbLargeCommandLine.focus();
+
+            if (Firebug.CommandLine)
+                Firebug.CommandLine.setMultiLine(true);
+        }
+    },
+
+    hideLargeCommandLine: function()
+    {
+        if (Firebug.chrome.largeCommandLineVisible)
+        {
+            Firebug.chrome.largeCommandLineVisible = false;
+
+            if (Firebug.CommandLine)
+                Firebug.CommandLine.setMultiLine(false);
+
+            fbLargeCommandLine.blur();
+
+            fbPanel2Style.display = "block";
+            fbPanelBar2BoxStyle.display = "block";
+
+            fbLargeCommandLine.style.display = "none";
+            fbLargeCommandButtons.style.display = "none";
+
+            changeSidePanelVisibility(false);
+
+            if (Firebug.chrome.selectedPanel.options.hasCommandLine)
+                changeCommandLineVisibility(true);
+
+            Firebug.chrome.draw();
+
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    focusCommandLine: function()
+    {
+        var selectedPanelName = this.selectedPanel.name, panelToSelect;
+
+        if (focusCommandLineState == 0 || selectedPanelName != "Console")
+        {
+            focusCommandLineState = 0;
+            lastFocusedPanelName = selectedPanelName;
+
+            panelToSelect = "Console";
+        }
+        if (focusCommandLineState == 1)
+        {
+            panelToSelect = lastFocusedPanelName;
+        }
+
+        this.selectPanel(panelToSelect);
+
+        try
+        {
+            if (Firebug.CommandLine)
+            {
+                if (panelToSelect == "Console")
+                    Firebug.CommandLine.focus();
+                else
+                    Firebug.CommandLine.blur();
+            }
+        }
+        catch(e)
+        {
+            //TODO: xxxpedro trace error
+        }
+
+        focusCommandLineState = ++focusCommandLineState % 2;
+    }
+
+});
+
+// ************************************************************************************************
+// ChromeFrameBase
+
+/**
+ * @namespace
+ * @extends ns-chrome-ChromeBase
+ */
+var ChromeFrameBase = extend(ChromeBase,
+/**@extend ns-chrome-ChromeFrameBase*/
+{
+    create: function()
+    {
+        ChromeBase.create.call(this);
+
+        // restore display for the anti-flicker trick
+        if (isFirefox)
+            this.node.style.display = "block";
+
+        if (Env.Options.startInNewWindow)
+        {
+            this.close();
+            this.toggle(true, true);
+            return;
+        }
+
+        if (Env.Options.startOpened)
+            this.open();
+        else
+            this.close();
+    },
+
+    destroy: function()
+    {
+        var size = Firebug.chrome.getWindowSize();
+
+        Firebug.context.persistedState.height = size.height;
+
+        if (Firebug.saveCookies)
+            Firebug.savePrefs();
+
+        removeGlobalEvent("keydown", onGlobalKeyDown);
+
+        ChromeBase.destroy.call(this);
+
+        this.document = null;
+        delete this.document;
+
+        this.window = null;
+        delete this.window;
+
+        this.node.parentNode.removeChild(this.node);
+        this.node = null;
+        delete this.node;
+    },
+
+    initialize: function()
+    {
+        //FBTrace.sysout("Frame", "initialize();")
+        ChromeBase.initialize.call(this);
+
+        this.addController(
+            [Firebug.browser.window, "resize", this.resize],
+            [$("fbWindow_btClose"), "click", this.close],
+            [$("fbWindow_btDetach"), "click", this.detach],
+            [$("fbWindow_btDeactivate"), "click", this.deactivate]
+        );
+
+        if (!Env.Options.enablePersistent)
+            this.addController([Firebug.browser.window, "unload", Firebug.shutdown]);
+
+        if (noFixedPosition)
+        {
+            this.addController(
+                [Firebug.browser.window, "scroll", this.fixIEPosition]
+            );
+        }
+
+        fbVSplitter.onmousedown = onVSplitterMouseDown;
+        fbHSplitter.onmousedown = onHSplitterMouseDown;
+
+        this.isInitialized = true;
+    },
+
+    shutdown: function()
+    {
+        fbVSplitter.onmousedown = null;
+        fbHSplitter.onmousedown = null;
+
+        ChromeBase.shutdown.apply(this);
+
+        this.isInitialized = false;
+    },
+
+    reattach: function()
+    {
+        var frame = FirebugChrome.chromeMap.frame;
+
+        ChromeBase.reattach(FirebugChrome.chromeMap.popup, this);
+    },
+
+    open: function()
+    {
+        if (!Firebug.context.persistedState.isOpen)
+        {
+            Firebug.context.persistedState.isOpen = true;
+
+            if (Env.isChromeExtension)
+                localStorage.setItem("Firebug", "1,1");
+
+            var node = this.node;
+
+            node.style.visibility = "hidden"; // Avoid flickering
+
+            if (Firebug.showIconWhenHidden)
+            {
+                if (ChromeMini.isInitialized)
+                {
+                    ChromeMini.shutdown();
+                }
+
+            }
+            else
+                node.style.display = "block";
+
+            var main = $("fbChrome");
+
+            // IE6 throws an error when setting this property! why?
+            //main.style.display = "table";
+            main.style.display = "";
+
+            var self = this;
+                /// TODO: xxxpedro FOUC
+                node.style.visibility = "visible";
+            setTimeout(function(){
+                ///node.style.visibility = "visible";
+
+                //dispatch(Firebug.modules, "initialize", []);
+                self.initialize();
+
+                if (noFixedPosition)
+                    self.fixIEPosition();
+
+                self.draw();
+
+            }, 10);
+        }
+    },
+
+    close: function()
+    {
+        if (Firebug.context.persistedState.isOpen)
+        {
+            if (this.isInitialized)
+            {
+                //dispatch(Firebug.modules, "shutdown", []);
+                this.shutdown();
+            }
+
+            Firebug.context.persistedState.isOpen = false;
+
+            if (Env.isChromeExtension)
+                localStorage.setItem("Firebug", "1,0");
+
+            var node = this.node;
+
+            if (Firebug.showIconWhenHidden)
+            {
+                node.style.visibility = "hidden"; // Avoid flickering
+
+                // TODO: xxxpedro - persist IE fixed?
+                var main = $("fbChrome", FirebugChrome.chromeMap.frame.document);
+                main.style.display = "none";
+
+                ChromeMini.initialize();
+
+                node.style.visibility = "visible";
+            }
+            else
+                node.style.display = "none";
+        }
+    },
+
+    deactivate: function()
+    {
+        // if it is running as a Chrome extension, dispatch a message to the extension signaling
+        // that Firebug should be deactivated for the current tab
+        if (Env.isChromeExtension)
+        {
+            localStorage.removeItem("Firebug");
+            Firebug.GoogleChrome.dispatch("FB_deactivate");
+
+            // xxxpedro problem here regarding Chrome extension. We can't deactivate the whole
+            // app, otherwise it won't be able to be reactivated without reloading the page.
+            // but we need to stop listening global keys, otherwise the key activation won't work.
+            Firebug.chrome.close();
+        }
+        else
+        {
+            Firebug.shutdown();
+        }
+    },
+
+    fixIEPosition: function()
+    {
+        // fix IE problem with offset when not in fullscreen mode
+        var doc = this.document;
+        var offset = isIE ? doc.body.clientTop || doc.documentElement.clientTop: 0;
+
+        var size = Firebug.browser.getWindowSize();
+        var scroll = Firebug.browser.getWindowScrollPosition();
+        var maxHeight = size.height;
+        var height = this.node.offsetHeight;
+
+        var bodyStyle = doc.body.currentStyle;
+
+        this.node.style.top = maxHeight - height + scroll.top + "px";
+
+        if ((this.type == "frame" || this.type == "div") &&
+            (bodyStyle.marginLeft || bodyStyle.marginRight))
+        {
+            this.node.style.width = size.width + "px";
+        }
+
+        if (fbVSplitterStyle)
+            fbVSplitterStyle.right = Firebug.context.persistedState.sidePanelWidth + "px";
+
+        this.draw();
+    }
+
+});
+
+
+// ************************************************************************************************
+// ChromeMini
+
+/**
+ * @namespace
+ * @extends FBL.Controller
+ */
+var ChromeMini = extend(Controller,
+/**@extend ns-chrome-ChromeMini*/
+{
+    create: function(chrome)
+    {
+        append(this, chrome);
+        this.type = "mini";
+    },
+
+    initialize: function()
+    {
+        Controller.initialize.apply(this);
+
+        var doc = FirebugChrome.chromeMap.frame.document;
+
+        var mini = $("fbMiniChrome", doc);
+        mini.style.display = "block";
+
+        var miniIcon = $("fbMiniIcon", doc);
+        var width = miniIcon.offsetWidth + 10;
+        miniIcon.title = "Open " + Firebug.version;
+
+        var errors = $("fbMiniErrors", doc);
+        if (errors.offsetWidth)
+            width += errors.offsetWidth + 10;
+
+        var node = this.node;
+        node.style.height = "27px";
+        node.style.width = width + "px";
+        node.style.left = "";
+        node.style.right = 0;
+
+        if (this.node.nodeName.toLowerCase() == "iframe")
+        {
+            node.setAttribute("allowTransparency", "true");
+            this.document.body.style.backgroundColor = "transparent";
+        }
+        else
+            node.style.background = "transparent";
+
+        if (noFixedPosition)
+            this.fixIEPosition();
+
+        this.addController(
+            [$("fbMiniIcon", doc), "click", onMiniIconClick]
+        );
+
+        if (noFixedPosition)
+        {
+            this.addController(
+                [Firebug.browser.window, "scroll", this.fixIEPosition]
+            );
+        }
+
+        this.isInitialized = true;
+    },
+
+    shutdown: function()
+    {
+        var node = this.node;
+        node.style.height = Firebug.context.persistedState.height + "px";
+        node.style.width = "100%";
+        node.style.left = 0;
+        node.style.right = "";
+
+        if (this.node.nodeName.toLowerCase() == "iframe")
+        {
+            node.setAttribute("allowTransparency", "false");
+            this.document.body.style.backgroundColor = "#fff";
+        }
+        else
+            node.style.background = "#fff";
+
+        if (noFixedPosition)
+            this.fixIEPosition();
+
+        var doc = FirebugChrome.chromeMap.frame.document;
+
+        var mini = $("fbMiniChrome", doc);
+        mini.style.display = "none";
+
+        Controller.shutdown.apply(this);
+
+        this.isInitialized = false;
+    },
+
+    draw: function()
+    {
+
+    },
+
+    fixIEPosition: ChromeFrameBase.fixIEPosition
+
+});
+
+
+// ************************************************************************************************
+// ChromePopupBase
+
+/**
+ * @namespace
+ * @extends ns-chrome-ChromeBase
+ */
+var ChromePopupBase = extend(ChromeBase,
+/**@extend ns-chrome-ChromePopupBase*/
+{
+
+    initialize: function()
+    {
+        setClass(this.document.body, "FirebugPopup");
+
+        ChromeBase.initialize.call(this);
+
+        this.addController(
+            [Firebug.chrome.window, "resize", this.resize],
+            [Firebug.chrome.window, "unload", this.destroy]
+            //[Firebug.chrome.window, "beforeunload", this.destroy]
+        );
+
+        if (Env.Options.enablePersistent)
+        {
+            this.persist = bind(this.persist, this);
+            addEvent(Firebug.browser.window, "unload", this.persist);
+        }
+        else
+            this.addController(
+                [Firebug.browser.window, "unload", this.close]
+            );
+
+        fbVSplitter.onmousedown = onVSplitterMouseDown;
+    },
+
+    destroy: function()
+    {
+        var chromeWin = Firebug.chrome.window;
+        var left = chromeWin.screenX || chromeWin.screenLeft;
+        var top = chromeWin.screenY || chromeWin.screenTop;
+        var size = Firebug.chrome.getWindowSize();
+
+        Firebug.context.persistedState.popupTop = top;
+        Firebug.context.persistedState.popupLeft = left;
+        Firebug.context.persistedState.popupWidth = size.width;
+        Firebug.context.persistedState.popupHeight = size.height;
+
+        if (Firebug.saveCookies)
+            Firebug.savePrefs();
+
+        // TODO: xxxpedro sync detach reattach attach
+        var frame = FirebugChrome.chromeMap.frame;
+
+        if(frame)
+        {
+            dispatch(frame.panelMap, "detach", [this, frame]);
+
+            frame.reattach(this, frame);
+        }
+
+        if (Env.Options.enablePersistent)
+        {
+            removeEvent(Firebug.browser.window, "unload", this.persist);
+        }
+
+        ChromeBase.destroy.apply(this);
+
+        FirebugChrome.chromeMap.popup = null;
+
+        this.node.close();
+    },
+
+    persist: function()
+    {
+        persistTimeStart = new Date().getTime();
+
+        removeEvent(Firebug.browser.window, "unload", this.persist);
+
+        Firebug.Inspector.destroy();
+        Firebug.browser.window.FirebugOldBrowser = true;
+
+        var persistTimeStart = new Date().getTime();
+
+        var waitMainWindow = function()
+        {
+            var doc, head;
+
+            try
+            {
+                if (window.opener && !window.opener.FirebugOldBrowser && (doc = window.opener.document)/* &&
+                    doc.documentElement && (head = doc.documentElement.firstChild)*/)
+                {
+
+                    try
+                    {
+                        // exposes the FBL to the global namespace when in debug mode
+                        if (Env.isDebugMode)
+                        {
+                            window.FBL = FBL;
+                        }
+
+                        window.Firebug = Firebug;
+                        window.opener.Firebug = Firebug;
+
+                        Env.browser = window.opener;
+                        Firebug.browser = Firebug.context = new Context(Env.browser);
+                        Firebug.loadPrefs();
+
+                        registerConsole();
+
+                        // the delay time should be calculated right after registering the
+                        // console, once right after the console registration, call log messages
+                        // will be properly handled
+                        var persistDelay = new Date().getTime() - persistTimeStart;
+
+                        var chrome = Firebug.chrome;
+                        addEvent(Firebug.browser.window, "unload", chrome.persist);
+
+                        FBL.cacheDocument();
+                        Firebug.Inspector.create();
+
+                        Firebug.Console.logFormatted(
+                            ["Firebug could not capture console calls during " +
+                            persistDelay + "ms"],
+                            Firebug.context,
+                            "info"
+                        );
+
+                        setTimeout(function(){
+                            var htmlPanel = chrome.getPanel("HTML");
+                            htmlPanel.createUI();
+                        },50);
+
+                    }
+                    catch(pE)
+                    {
+                        alert("persist error: " + (pE.message || pE));
+                    }
+
+                }
+                else
+                {
+                    window.setTimeout(waitMainWindow, 0);
+                }
+
+            } catch (E) {
+                window.close();
+            }
+        };
+
+        waitMainWindow();
+    },
+
+    close: function()
+    {
+        this.destroy();
+    }
+
+});
+
+
+//************************************************************************************************
+// UI helpers
+
+var changeCommandLineVisibility = function changeCommandLineVisibility(visibility)
+{
+    var last = Firebug.chrome.commandLineVisible;
+    var visible = Firebug.chrome.commandLineVisible =
+        typeof visibility == "boolean" ? visibility : !Firebug.chrome.commandLineVisible;
+
+    if (visible != last)
+    {
+        if (visible)
+        {
+            fbBottom.className = "";
+
+            if (Firebug.CommandLine)
+                Firebug.CommandLine.activate();
+        }
+        else
+        {
+            if (Firebug.CommandLine)
+                Firebug.CommandLine.deactivate();
+
+            fbBottom.className = "hide";
+        }
+    }
+};
+
+var changeSidePanelVisibility = function changeSidePanelVisibility(visibility)
+{
+    var last = Firebug.chrome.sidePanelVisible;
+    Firebug.chrome.sidePanelVisible =
+        typeof visibility == "boolean" ? visibility : !Firebug.chrome.sidePanelVisible;
+
+    if (Firebug.chrome.sidePanelVisible != last)
+    {
+        fbPanelBox2.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
+        fbPanelBar2Box.className = Firebug.chrome.sidePanelVisible ? "" : "hide";
+    }
+};
+
+
+// ************************************************************************************************
+// F12 Handler
+
+var onGlobalKeyDown = function onGlobalKeyDown(event)
+{
+    var keyCode = event.keyCode;
+    var shiftKey = event.shiftKey;
+    var ctrlKey = event.ctrlKey;
+
+    if (keyCode == 123 /* F12 */ && (!isFirefox && !shiftKey || shiftKey && isFirefox))
+    {
+        Firebug.chrome.toggle(false, ctrlKey);
+        cancelEvent(event, true);
+
+        // TODO: xxxpedro replace with a better solution. we're doing this
+        // to allow reactivating with the F12 key after being deactivated
+        if (Env.isChromeExtension)
+        {
+            Firebug.GoogleChrome.dispatch("FB_enableIcon");
+        }
+    }
+    else if (keyCode == 67 /* C */ && ctrlKey && shiftKey)
+    {
+        Firebug.Inspector.toggleInspect();
+        cancelEvent(event, true);
+    }
+    else if (keyCode == 76 /* L */ && ctrlKey && shiftKey)
+    {
+        Firebug.chrome.focusCommandLine();
+        cancelEvent(event, true);
+    }
+};
+
+var onMiniIconClick = function onMiniIconClick(event)
+{
+    Firebug.chrome.toggle(false, event.ctrlKey);
+    cancelEvent(event, true);
+};
+
+
+// ************************************************************************************************
+// Horizontal Splitter Handling
+
+var onHSplitterMouseDown = function onHSplitterMouseDown(event)
+{
+    addGlobalEvent("mousemove", onHSplitterMouseMove);
+    addGlobalEvent("mouseup", onHSplitterMouseUp);
+
+    if (isIE)
+        addEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
+
+    fbHSplitter.className = "fbOnMovingHSplitter";
+
+    return false;
+};
+
+var onHSplitterMouseMove = function onHSplitterMouseMove(event)
+{
+    cancelEvent(event, true);
+
+    var clientY = event.clientY;
+    var win = isIE
+        ? event.srcElement.ownerDocument.parentWindow
+        : event.target.defaultView || event.target.ownerDocument && event.target.ownerDocument.defaultView;
+
+    if (!win)
+        return;
+
+    if (win != win.parent)
+    {
+        var frameElement = win.frameElement;
+        if (frameElement)
+        {
+            var framePos = Firebug.browser.getElementPosition(frameElement).top;
+            clientY += framePos;
+
+            if (frameElement.style.position != "fixed")
+                clientY -= Firebug.browser.getWindowScrollPosition().top;
+        }
+    }
+
+    if (isOpera && isQuiksMode && win.frameElement.id == "FirebugUI")
+    {
+        clientY = Firebug.browser.getWindowSize().height - win.frameElement.offsetHeight + clientY;
+    }
+
+    /*
+    console.log(
+            typeof win.FBL != "undefined" ? "no-Chrome" : "Chrome",
+            //win.frameElement.id,
+            event.target,
+            clientY
+        );/**/
+
+    onHSplitterMouseMoveBuffer = clientY; // buffer
+
+    if (new Date().getTime() - lastHSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
+    {
+        lastHSplitterMouseMove = new Date().getTime();
+        handleHSplitterMouseMove();
+    }
+    else
+        if (!onHSplitterMouseMoveTimer)
+            onHSplitterMouseMoveTimer = setTimeout(handleHSplitterMouseMove, chromeRedrawSkipRate);
+
+    // improving the resizing performance by canceling the mouse event.
+    // canceling events will prevent the page to receive such events, which would imply
+    // in more processing being expended.
+    cancelEvent(event, true);
+    return false;
+};
+
+var handleHSplitterMouseMove = function()
+{
+    if (onHSplitterMouseMoveTimer)
+    {
+        clearTimeout(onHSplitterMouseMoveTimer);
+        onHSplitterMouseMoveTimer = null;
+    }
+
+    var clientY = onHSplitterMouseMoveBuffer;
+
+    var windowSize = Firebug.browser.getWindowSize();
+    var scrollSize = Firebug.browser.getWindowScrollSize();
+
+    // compute chrome fixed size (top bar and command line)
+    var commandLineHeight = Firebug.chrome.commandLineVisible ? fbCommandLine.offsetHeight : 0;
+    var fixedHeight = topHeight + commandLineHeight;
+    var chromeNode = Firebug.chrome.node;
+
+    var scrollbarSize = !isIE && (scrollSize.width > windowSize.width) ? 17 : 0;
+
+    //var height = !isOpera ? chromeNode.offsetTop + chromeNode.clientHeight : windowSize.height;
+    var height =  windowSize.height;
+
+    // compute the min and max size of the chrome
+    var chromeHeight = Math.max(height - clientY + 5 - scrollbarSize, fixedHeight);
+        chromeHeight = Math.min(chromeHeight, windowSize.height - scrollbarSize);
+
+    Firebug.context.persistedState.height = chromeHeight;
+    chromeNode.style.height = chromeHeight + "px";
+
+    if (noFixedPosition)
+        Firebug.chrome.fixIEPosition();
+
+    Firebug.chrome.draw();
+};
+
+var onHSplitterMouseUp = function onHSplitterMouseUp(event)
+{
+    removeGlobalEvent("mousemove", onHSplitterMouseMove);
+    removeGlobalEvent("mouseup", onHSplitterMouseUp);
+
+    if (isIE)
+        removeEvent(Firebug.browser.document.documentElement, "mouseleave", onHSplitterMouseUp);
+
+    fbHSplitter.className = "";
+
+    Firebug.chrome.draw();
+
+    // avoid text selection in IE when returning to the document
+    // after the mouse leaves the document during the resizing
+    return false;
+};
+
+
+// ************************************************************************************************
+// Vertical Splitter Handling
+
+var onVSplitterMouseDown = function onVSplitterMouseDown(event)
+{
+    addGlobalEvent("mousemove", onVSplitterMouseMove);
+    addGlobalEvent("mouseup", onVSplitterMouseUp);
+
+    return false;
+};
+
+var onVSplitterMouseMove = function onVSplitterMouseMove(event)
+{
+    if (new Date().getTime() - lastVSplitterMouseMove > chromeRedrawSkipRate) // frame skipping
+    {
+        var target = event.target || event.srcElement;
+        if (target && target.ownerDocument) // avoid error when cursor reaches out of the chrome
+        {
+            var clientX = event.clientX;
+            var win = document.all
+                ? event.srcElement.ownerDocument.parentWindow
+                : event.target.ownerDocument.defaultView;
+
+            if (win != win.parent)
+                clientX += win.frameElement ? win.frameElement.offsetLeft : 0;
+
+            var size = Firebug.chrome.getSize();
+            var x = Math.max(size.width - clientX + 3, 6);
+
+            Firebug.context.persistedState.sidePanelWidth = x;
+            Firebug.chrome.draw();
+        }
+
+        lastVSplitterMouseMove = new Date().getTime();
+    }
+
+    cancelEvent(event, true);
+    return false;
+};
+
+var onVSplitterMouseUp = function onVSplitterMouseUp(event)
+{
+    removeGlobalEvent("mousemove", onVSplitterMouseMove);
+    removeGlobalEvent("mouseup", onVSplitterMouseUp);
+
+    Firebug.chrome.draw();
+};
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+Firebug.Lite =
+{
+};
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+Firebug.Lite.Cache =
+{
+    ID: "firebug-" + new Date().getTime()
+};
+
+// ************************************************************************************************
+
+/**
+ * TODO: if a cached element is cloned, the expando property will be cloned too in IE
+ * which will result in a bug. Firebug Lite will think the new cloned node is the old
+ * one.
+ *
+ * TODO: Investigate a possibility of cache validation, to be customized by each
+ * kind of cache. For ElementCache it should validate if the element still is
+ * inserted at the DOM.
+ */
+var cacheUID = 0;
+var createCache = function()
+{
+    var map = {};
+    var data = {};
+
+    var CID = Firebug.Lite.Cache.ID;
+
+    // better detection
+    var supportsDeleteExpando = !document.all;
+
+    var cacheFunction = function(element)
+    {
+        return cacheAPI.set(element);
+    };
+
+    var cacheAPI =
+    {
+        get: function(key)
+        {
+            return map.hasOwnProperty(key) ?
+                    map[key] :
+                    null;
+        },
+
+        set: function(element)
+        {
+            var id = getValidatedKey(element);
+
+            if (!id)
+            {
+                id = ++cacheUID;
+                element[CID] = id;
+            }
+
+            if (!map.hasOwnProperty(id))
+            {
+                map[id] = element;
+                data[id] = {};
+            }
+
+            return id;
+        },
+
+        unset: function(element)
+        {
+            var id = getValidatedKey(element);
+
+            if (!id) return;
+
+            if (supportsDeleteExpando)
+            {
+                delete element[CID];
+            }
+            else if (element.removeAttribute)
+            {
+                element.removeAttribute(CID);
+            }
+
+            delete map[id];
+            delete data[id];
+
+        },
+
+        key: function(element)
+        {
+            return getValidatedKey(element);
+        },
+
+        has: function(element)
+        {
+            var id = getValidatedKey(element);
+            return id && map.hasOwnProperty(id);
+        },
+
+        each: function(callback)
+        {
+            for (var key in map)
+            {
+                if (map.hasOwnProperty(key))
+                {
+                    callback(key, map[key]);
+                }
+            }
+        },
+
+        data: function(element, name, value)
+        {
+            // set data
+            if (value)
+            {
+                if (!name) return null;
+
+                var id = cacheAPI.set(element);
+
+                return data[id][name] = value;
+            }
+            // get data
+            else
+            {
+                var id = cacheAPI.key(element);
+
+                return data.hasOwnProperty(id) && data[id].hasOwnProperty(name) ?
+                        data[id][name] :
+                        null;
+            }
+        },
+
+        clear: function()
+        {
+            for (var id in map)
+            {
+                var element = map[id];
+                cacheAPI.unset(element);
+            }
+        }
+    };
+
+    var getValidatedKey = function(element)
+    {
+        var id = element[CID];
+
+        // If a cached element is cloned in IE, the expando property CID will be also
+        // cloned (differently than other browsers) resulting in a bug: Firebug Lite
+        // will think the new cloned node is the old one. To prevent this problem we're
+        // checking if the cached element matches the given element.
+        if (
+            !supportsDeleteExpando &&   // the problem happens when supportsDeleteExpando is false
+            id &&                       // the element has the expando property
+            map.hasOwnProperty(id) &&   // there is a cached element with the same id
+            map[id] != element          // but it is a different element than the current one
+            )
+        {
+            // remove the problematic property
+            element.removeAttribute(CID);
+
+            id = null;
+        }
+
+        return id;
+    };
+
+    FBL.append(cacheFunction, cacheAPI);
+
+    return cacheFunction;
+};
+
+// ************************************************************************************************
+
+// TODO: xxxpedro : check if we need really this on FBL scope
+Firebug.Lite.Cache.StyleSheet = createCache();
+Firebug.Lite.Cache.Element = createCache();
+
+// TODO: xxxpedro
+Firebug.Lite.Cache.Event = createCache();
+
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+var sourceMap = {};
+
+// ************************************************************************************************
+Firebug.Lite.Proxy =
+{
+    // jsonp callbacks
+    _callbacks: {},
+
+    /**
+     * Load a resource, either locally (directly) or externally (via proxy) using
+     * synchronous XHR calls. Loading external resources requires the proxy plugin to
+     * be installed and configured (see /plugin/proxy/proxy.php).
+     */
+    load: function(url)
+    {
+        var resourceDomain = getDomain(url);
+        var isLocalResource =
+            // empty domain means local URL
+            !resourceDomain ||
+            // same domain means local too
+            resourceDomain ==  Firebug.context.window.location.host; // TODO: xxxpedro context
+
+        return isLocalResource ? fetchResource(url) : fetchProxyResource(url);
+    },
+
+    /**
+     * Load a resource using JSONP technique.
+     */
+    loadJSONP: function(url, callback)
+    {
+        var script = createGlobalElement("script"),
+            doc = Firebug.context.document,
+
+            uid = "" + new Date().getTime(),
+            callbackName = "callback=Firebug.Lite.Proxy._callbacks." + uid,
+
+            jsonpURL = url.indexOf("?") != -1 ?
+                    url + "&" + callbackName :
+                    url + "?" + callbackName;
+
+        Firebug.Lite.Proxy._callbacks[uid] = function(data)
+        {
+            if (callback)
+                callback(data);
+
+            script.parentNode.removeChild(script);
+            delete Firebug.Lite.Proxy._callbacks[uid];
+        };
+
+        script.src = jsonpURL;
+
+        if (doc.documentElement)
+            doc.documentElement.appendChild(script);
+    },
+
+    /**
+     * Load a resource using YQL (not reliable).
+     */
+    YQL: function(url, callback)
+    {
+        var yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" +
+                encodeURIComponent(url) + "%22&format=xml";
+
+        this.loadJSONP(yql, function(data)
+        {
+            var source = data.results[0];
+
+            // clean up YQL bogus elements
+            var match = /<body>\s+<p>([\s\S]+)<\/p>\s+<\/body>$/.exec(source);
+            if (match)
+                source = match[1];
+
+            console.log(source);
+        });
+    }
+};
+
+// ************************************************************************************************
+
+Firebug.Lite.Proxy.fetchResourceDisabledMessage =
+    "/* Firebug Lite resource fetching is disabled.\n" +
+    "To enabled it set the Firebug Lite option \"disableResourceFetching\" to \"false\".\n" +
+    "More info at http://getfirebug.com/firebuglite#Options */";
+
+var fetchResource = function(url)
+{
+    if (Firebug.disableResourceFetching)
+    {
+        var source = sourceMap[url] = Firebug.Lite.Proxy.fetchResourceDisabledMessage;
+        return source;
+    }
+
+    if (sourceMap.hasOwnProperty(url))
+        return sourceMap[url];
+
+    // Getting the native XHR object so our calls won't be logged in the Console Panel
+    var xhr = FBL.getNativeXHRObject();
+    xhr.open("get", url, false);
+    xhr.send();
+
+    var source = sourceMap[url] = xhr.responseText;
+    return source;
+};
+
+var fetchProxyResource = function(url)
+{
+    if (sourceMap.hasOwnProperty(url))
+        return sourceMap[url];
+
+    var proxyURL = Env.Location.baseDir + "plugin/proxy/proxy.php?url=" + encodeURIComponent(url);
+    var response = fetchResource(proxyURL);
+
+    try
+    {
+        var data = eval("(" + response + ")");
+    }
+    catch(E)
+    {
+        return "ERROR: Firebug Lite Proxy plugin returned an invalid response.";
+    }
+
+    var source = data ? data.contents : "";
+    return source;
+};
+
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+Firebug.Lite.Style =
+{
+};
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+Firebug.Lite.Script = function(window)
+{
+    this.fileName = null;
+    this.isValid = null;
+    this.baseLineNumber = null;
+    this.lineExtent = null;
+    this.tag = null;
+
+    this.functionName = null;
+    this.functionSource = null;
+};
+
+Firebug.Lite.Script.prototype =
+{
+    isLineExecutable: function(){},
+    pcToLine: function(){},
+    lineToPc: function(){},
+
+    toString: function()
+    {
+        return "Firebug.Lite.Script";
+    }
+};
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+
+Firebug.Lite.Browser = function(window)
+{
+    this.contentWindow = window;
+    this.contentDocument = window.document;
+    this.currentURI =
+    {
+        spec: window.location.href
+    };
+};
+
+Firebug.Lite.Browser.prototype =
+{
+    toString: function()
+    {
+        return "Firebug.Lite.Browser";
+    }
+};
+
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+/*
+    http://www.JSON.org/json2.js
+    2010-03-20
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 ? '0' + n : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date ?
+                    'Date(' + this[key] + ')' : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint evil: true, strict: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+// ************************************************************************************************
+
+var JSON = window.JSON || {};
+
+// ************************************************************************************************
+
+(function () {
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 ? '0' + n : n;
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function (key) {
+
+            return isFinite(this.valueOf()) ?
+                   this.getUTCFullYear()   + '-' +
+                 f(this.getUTCMonth() + 1) + '-' +
+                 f(this.getUTCDate())      + 'T' +
+                 f(this.getUTCHours())     + ':' +
+                 f(this.getUTCMinutes())   + ':' +
+                 f(this.getUTCSeconds())   + 'Z' : null;
+        };
+
+        String.prototype.toJSON =
+        Number.prototype.toJSON =
+        Boolean.prototype.toJSON = function (key) {
+            return this.valueOf();
+        };
+    }
+
+    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        gap,
+        indent,
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"' : '\\"',
+            '\\': '\\\\'
+        },
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        escapable.lastIndex = 0;
+        return escapable.test(string) ?
+            '"' + string.replace(escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string' ? c :
+                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' :
+            '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) ? String(value) : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0 ? '[]' :
+                    gap ? '[\n' + gap +
+                            partial.join(',\n' + gap) + '\n' +
+                                mind + ']' :
+                          '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    k = rep[i];
+                    if (typeof k === 'string') {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0 ? '{}' :
+                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+                        mind + '}' : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                     typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            cx.lastIndex = 0;
+            if (cx.test(text)) {
+                text = text.replace(cx, function (a) {
+                    return '\\u' +
+                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function' ?
+                    walk({'': j}, '') : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+
+// ************************************************************************************************
+// registration
+
+FBL.JSON = JSON;
+
+// ************************************************************************************************
+}());
+
+/* See license.txt for terms of usage */
+
+(function(){
+// ************************************************************************************************
+
+/* Copyright (c) 2010-2011 Marcus Westin
+ *
+ * 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.
+ */
+
+var store = (function(){
+	var api = {},
+		win = window,
+		doc = win.document,
+		localStorageName = 'localStorage',
+		globalStorageName = 'globalStorage',
+		namespace = '__firebug__storejs__',
+		storage
+
+	api.disabled = false
+	api.set = function(key, value) {}
+	api.get = function(key) {}
+	api.remove = function(key) {}
+	api.clear = function() {}
+	api.transact = function(key, transactionFn) {
+		var val = api.get(key)
+		if (typeof val == 'undefined') { val = {} }
+		transactionFn(val)
+		api.set(key, val)
+	}
+
+	api.serialize = function(value) {
+		return JSON.stringify(value)
+	}
+	api.deserialize = function(value) {
+		if (typeof value != 'string') { return undefined }
+		return JSON.parse(value)
+	}
+
+	// Functions to encapsulate questionable FireFox 3.6.13 behavior
+	// when about.config::dom.storage.enabled === false
+	// See https://github.com/marcuswestin/store.js/issues#issue/13
+	function isLocalStorageNameSupported() {
+		try { return (localStorageName in win && win[localStorageName]) }
+		catch(err) { return false }
+	}
+
+	function isGlobalStorageNameSupported() {
+		try { return (globalStorageName in win && win[globalStorageName] && win[globalStorageName][win.location.hostname]) }
+		catch(err) { return false }
+	}
+
+	if (isLocalStorageNameSupported()) {
+		storage = win[localStorageName]
+		api.set = function(key, val) { storage.setItem(key, api.serialize(val)) }
+		api.get = function(key) { return api.deserialize(storage.getItem(key)) }
+		api.remove = function(key) { storage.removeItem(key) }
+		api.clear = function() { storage.clear() }
+
+	} else if (isGlobalStorageNameSupported()) {
+		storage = win[globalStorageName][win.location.hostname]
+		api.set = function(key, val) { storage[key] = api.serialize(val) }
+		api.get = function(key) { return api.deserialize(storage[key] && storage[key].value) }
+		api.remove = function(key) { delete storage[key] }
+		api.clear = function() { for (var key in storage ) { delete storage[key] } }
+
+	} else if (doc.documentElement.addBehavior) {
+		var storage = doc.createElement('div')
+		function withIEStorage(storeFunction) {
+			return function() {
+				var args = Array.prototype.slice.call(arguments, 0)
+				args.unshift(storage)
+				// See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
+				// and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
+				// TODO: xxxpedro doc.body is not always available so we must use doc.documentElement.
+				// We need to make sure this change won't affect the behavior of this library.
+				doc.documentElement.appendChild(storage)
+				storage.addBehavior('#default#userData')
+				storage.load(localStorageName)
+				var result = storeFunction.apply(api, args)
+				doc.documentElement.removeChild(storage)
+				return result
+			}
+		}
+		api.set = withIEStorage(function(storage, key, val) {
+			storage.setAttribute(key, api.serialize(val))
+			storage.save(localStorageName)
+		})
+		api.get = withIEStorage(function(storage, key) {
+			return api.deserialize(storage.getAttribute(key))
+		})
+		api.remove = withIEStorage(function(storage, key) {
+			storage.removeAttribute(key)
+			storage.save(localStorageName)
+		})
+		api.clear = withIEStorage(function(storage) {
+			var attributes = storage.XMLDocument.documentElement.attributes
+			storage.load(localStorageName)
+			for (var i=0, attr; attr = attributes[i]; i++) {
+				storage.removeAttribute(attr.name)
+			}
+			storage.save(localStorageName)
+		})
+	}
+
+	try {
+		api.set(namespace, namespace)
+		if (api.get(namespace) != namespace) { api.disabled = true }
+		api.remove(namespace)
+	} catch(e) {
+		api.disabled = true
+	}
+
+	return api
+})();
+
+if (typeof module != 'undefined') { module.exports = store }
+
+
+// ************************************************************************************************
+// registration
+
+FBL.Store = store;
+
+// ************************************************************************************************
+})();
+
+/* See license.txt for terms of usage */
+
+FBL.ns( /**@scope s_selector*/ function() { with (FBL) {
+// ************************************************************************************************
+
+/*
+ * Sizzle CSS Selector Engine - v1.0
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+    done = 0,
+    toString = Object.prototype.toString,
+    hasDuplicate = false,
+    baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+//   Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+    baseHasDuplicate = false;
+    return 0;
+});
+
+/**
+ * @name Firebug.Selector
+ * @namespace
+ */
+
+/**
+ * @exports Sizzle as Firebug.Selector
+ */
+var Sizzle = function(selector, context, results, seed) {
+    results = results || [];
+    var origContext = context = context || document;
+
+    if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+        return [];
+    }
+
+    if ( !selector || typeof selector !== "string" ) {
+        return results;
+    }
+
+    var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
+        soFar = selector;
+
+    // Reset the position of the chunker regexp (start from head)
+    while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+        soFar = m[3];
+
+        parts.push( m[1] );
+
+        if ( m[2] ) {
+            extra = m[3];
+            break;
+        }
+    }
+
+    if ( parts.length > 1 && origPOS.exec( selector ) ) {
+        if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+            set = posProcess( parts[0] + parts[1], context );
+        } else {
+            set = Expr.relative[ parts[0] ] ?
+                [ context ] :
+                Sizzle( parts.shift(), context );
+
+            while ( parts.length ) {
+                selector = parts.shift();
+
+                if ( Expr.relative[ selector ] )
+                    selector += parts.shift();
+
+                set = posProcess( selector, set );
+            }
+        }
+    } else {
+        // Take a shortcut and set the context if the root selector is an ID
+        // (but not if it'll be faster if the inner selector is an ID)
+        if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+                Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+            var ret = Sizzle.find( parts.shift(), context, contextXML );
+            context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+        }
+
+        if ( context ) {
+            var ret = seed ?
+                { expr: parts.pop(), set: makeArray(seed) } :
+                Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+            set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+            if ( parts.length > 0 ) {
+                checkSet = makeArray(set);
+            } else {
+                prune = false;
+            }
+
+            while ( parts.length ) {
+                var cur = parts.pop(), pop = cur;
+
+                if ( !Expr.relative[ cur ] ) {
+                    cur = "";
+                } else {
+                    pop = parts.pop();
+                }
+
+                if ( pop == null ) {
+                    pop = context;
+                }
+
+                Expr.relative[ cur ]( checkSet, pop, contextXML );
+            }
+        } else {
+            checkSet = parts = [];
+        }
+    }
+
+    if ( !checkSet ) {
+        checkSet = set;
+    }
+
+    if ( !checkSet ) {
+        throw "Syntax error, unrecognized expression: " + (cur || selector);
+    }
+
+    if ( toString.call(checkSet) === "[object Array]" ) {
+        if ( !prune ) {
+            results.push.apply( results, checkSet );
+        } else if ( context && context.nodeType === 1 ) {
+            for ( var i = 0; checkSet[i] != null; i++ ) {
+                if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+                    results.push( set[i] );
+                }
+            }
+        } else {
+            for ( var i = 0; checkSet[i] != null; i++ ) {
+                if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+                    results.push( set[i] );
+                }
+            }
+        }
+    } else {
+        makeArray( checkSet, results );
+    }
+
+    if ( extra ) {
+        Sizzle( extra, origContext, results, seed );
+        Sizzle.uniqueSort( results );
+    }
+
+    return results;
+};
+
+Sizzle.uniqueSort = function(results){
+    if ( sortOrder ) {
+        hasDuplicate = baseHasDuplicate;
+        results.sort(sortOrder);
+
+        if ( hasDuplicate ) {
+            for ( var i = 1; i < results.length; i++ ) {
+                if ( results[i] === results[i-1] ) {
+                    results.splice(i--, 1);
+                }
+            }
+        }
+    }
+
+    return results;
+};
+
+Sizzle.matches = function(expr, set){
+    return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+    var set, match;
+
+    if ( !expr ) {
+        return [];
+    }
+
+    for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+        var type = Expr.order[i], match;
+
+        if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+            var left = match[1];
+            match.splice(1,1);
+
+            if ( left.substr( left.length - 1 ) !== "\\" ) {
+                match[1] = (match[1] || "").replace(/\\/g, "");
+                set = Expr.find[ type ]( match, context, isXML );
+                if ( set != null ) {
+                    expr = expr.replace( Expr.match[ type ], "" );
+                    break;
+                }
+            }
+        }
+    }
+
+    if ( !set ) {
+        set = context.getElementsByTagName("*");
+    }
+
+    return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+    var old = expr, result = [], curLoop = set, match, anyFound,
+        isXMLFilter = set && set[0] && isXML(set[0]);
+
+    while ( expr && set.length ) {
+        for ( var type in Expr.filter ) {
+            if ( (match = Expr.match[ type ].exec( expr )) != null ) {
+                var filter = Expr.filter[ type ], found, item;
+                anyFound = false;
+
+                if ( curLoop == result ) {
+                    result = [];
+                }
+
+                if ( Expr.preFilter[ type ] ) {
+                    match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+                    if ( !match ) {
+                        anyFound = found = true;
+                    } else if ( match === true ) {
+                        continue;
+                    }
+                }
+
+                if ( match ) {
+                    for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+                        if ( item ) {
+                            found = filter( item, match, i, curLoop );
+                            var pass = not ^ !!found;
+
+                            if ( inplace && found != null ) {
+                                if ( pass ) {
+                                    anyFound = true;
+                                } else {
+                                    curLoop[i] = false;
+                                }
+                            } else if ( pass ) {
+                                result.push( item );
+                                anyFound = true;
+                            }
+                        }
+                    }
+                }
+
+                if ( found !== undefined ) {
+                    if ( !inplace ) {
+                        curLoop = result;
+                    }
+
+                    expr = expr.replace( Expr.match[ type ], "" );
+
+                    if ( !anyFound ) {
+                        return [];
+                    }
+
+                    break;
+                }
+            }
+        }
+
+        // Improper expression
+        if ( expr == old ) {
+            if ( anyFound == null ) {
+                throw "Syntax error, unrecognized expression: " + expr;
+            } else {
+                break;
+            }
+        }
+
+        old = expr;
+    }
+
+    return curLoop;
+};
+
+/**#@+ @ignore */
+var Expr = Sizzle.selectors = {
+    order: [ "ID", "NAME", "TAG" ],
+    match: {
+        ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+        CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+        NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+        ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+        TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+        CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+        POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+        PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
+    },
+    leftMatch: {},
+    attrMap: {
+        "class": "className",
+        "for": "htmlFor"
+    },
+    attrHandle: {
+        href: function(elem){
+            return elem.getAttribute("href");
+        }
+    },
+    relative: {
+        "+": function(checkSet, part, isXML){
+            var isPartStr = typeof part === "string",
+                isTag = isPartStr && !/\W/.test(part),
+                isPartStrNotTag = isPartStr && !isTag;
+
+            if ( isTag && !isXML ) {
+                part = part.toUpperCase();
+            }
+
+            for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+                if ( (elem = checkSet[i]) ) {
+                    while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+                    checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
+                        elem || false :
+                        elem === part;
+                }
+            }
+
+            if ( isPartStrNotTag ) {
+                Sizzle.filter( part, checkSet, true );
+            }
+        },
+        ">": function(checkSet, part, isXML){
+            var isPartStr = typeof part === "string";
+
+            if ( isPartStr && !/\W/.test(part) ) {
+                part = isXML ? part : part.toUpperCase();
+
+                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+                    var elem = checkSet[i];
+                    if ( elem ) {
+                        var parent = elem.parentNode;
+                        checkSet[i] = parent.nodeName === part ? parent : false;
+                    }
+                }
+            } else {
+                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+                    var elem = checkSet[i];
+                    if ( elem ) {
+                        checkSet[i] = isPartStr ?
+                            elem.parentNode :
+                            elem.parentNode === part;
+                    }
+                }
+
+                if ( isPartStr ) {
+                    Sizzle.filter( part, checkSet, true );
+                }
+            }
+        },
+        "": function(checkSet, part, isXML){
+            var doneName = done++, checkFn = dirCheck;
+
+            if ( !/\W/.test(part) ) {
+                var nodeCheck = part = isXML ? part : part.toUpperCase();
+                checkFn = dirNodeCheck;
+            }
+
+            checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+        },
+        "~": function(checkSet, part, isXML){
+            var doneName = done++, checkFn = dirCheck;
+
+            if ( typeof part === "string" && !/\W/.test(part) ) {
+                var nodeCheck = part = isXML ? part : part.toUpperCase();
+                checkFn = dirNodeCheck;
+            }
+
+            checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+        }
+    },
+    find: {
+        ID: function(match, context, isXML){
+            if ( typeof context.getElementById !== "undefined" && !isXML ) {
+                var m = context.getElementById(match[1]);
+                return m ? [m] : [];
+            }
+        },
+        NAME: function(match, context, isXML){
+            if ( typeof context.getElementsByName !== "undefined" ) {
+                var ret = [], results = context.getElementsByName(match[1]);
+
+                for ( var i = 0, l = results.length; i < l; i++ ) {
+                    if ( results[i].getAttribute("name") === match[1] ) {
+                        ret.push( results[i] );
+                    }
+                }
+
+                return ret.length === 0 ? null : ret;
+            }
+        },
+        TAG: function(match, context){
+            return context.getElementsByTagName(match[1]);
+        }
+    },
+    preFilter: {
+        CLASS: function(match, curLoop, inplace, result, not, isXML){
+            match = " " + match[1].replace(/\\/g, "") + " ";
+
+            if ( isXML ) {
+                return match;
+            }
+
+            for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+                if ( elem ) {
+                    if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
+                        if ( !inplace )
+                            result.push( elem );
+                    } else if ( inplace ) {
+                        curLoop[i] = false;
+                    }
+                }
+            }
+
+            return false;
+        },
+        ID: function(match){
+            return match[1].replace(/\\/g, "");
+        },
+        TAG: function(match, curLoop){
+            for ( var i = 0; curLoop[i] === false; i++ ){}
+            return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
+        },
+        CHILD: function(match){
+            if ( match[1] == "nth" ) {
+                // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+                var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+                    match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
+                    !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+                // calculate the numbers (first)n+(last) including if they are negative
+                match[2] = (test[1] + (test[2] || 1)) - 0;
+                match[3] = test[3] - 0;
+            }
+
+            // TODO: Move to normal caching system
+            match[0] = done++;
+
+            return match;
+        },
+        ATTR: function(match, curLoop, inplace, result, not, isXML){
+            var name = match[1].replace(/\\/g, "");
+
+            if ( !isXML && Expr.attrMap[name] ) {
+                match[1] = Expr.attrMap[name];
+            }
+
+            if ( match[2] === "~=" ) {
+                match[4] = " " + match[4] + " ";
+            }
+
+            return match;
+        },
+        PSEUDO: function(match, curLoop, inplace, result, not){
+            if ( match[1] === "not" ) {
+                // If we're dealing with a complex expression, or a simple one
+                if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+                    match[3] = Sizzle(match[3], null, null, curLoop);
+                } else {
+                    var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+                    if ( !inplace ) {
+                        result.push.apply( result, ret );
+                    }
+                    return false;
+                }
+            } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+                return true;
+            }
+
+            return match;
+        },
+        POS: function(match){
+            match.unshift( true );
+            return match;
+        }
+    },
+    filters: {
+        enabled: function(elem){
+            return elem.disabled === false && elem.type !== "hidden";
+        },
+        disabled: function(elem){
+            return elem.disabled === true;
+        },
+        checked: function(elem){
+            return elem.checked === true;
+        },
+        selected: function(elem){
+            // Accessing this property makes selected-by-default
+            // options in Safari work properly
+            elem.parentNode.selectedIndex;
+            return elem.selected === true;
+        },
+        parent: function(elem){
+            return !!elem.firstChild;
+        },
+        empty: function(elem){
+            return !elem.firstChild;
+        },
+        has: function(elem, i, match){
+            return !!Sizzle( match[3], elem ).length;
+        },
+        header: function(elem){
+            return /h\d/i.test( elem.nodeName );
+        },
+        text: function(elem){
+            return "text" === elem.type;
+        },
+        radio: function(elem){
+            return "radio" === elem.type;
+        },
+        checkbox: function(elem){
+            return "checkbox" === elem.type;
+        },
+        file: function(elem){
+            return "file" === elem.type;
+        },
+        password: function(elem){
+            return "password" === elem.type;
+        },
+        submit: function(elem){
+            return "submit" === elem.type;
+        },
+        image: function(elem){
+            return "image" === elem.type;
+        },
+        reset: function(elem){
+            return "reset" === elem.type;
+        },
+        button: function(elem){
+            return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
+        },
+        input: function(elem){
+            return /input|select|textarea|button/i.test(elem.nodeName);
+        }
+    },
+    setFilters: {
+        first: function(elem, i){
+            return i === 0;
+        },
+        last: function(elem, i, match, array){
+            return i === array.length - 1;
+        },
+        even: function(elem, i){
+            return i % 2 === 0;
+        },
+        odd: function(elem, i){
+            return i % 2 === 1;
+        },
+        lt: function(elem, i, match){
+            return i < match[3] - 0;
+        },
+        gt: function(elem, i, match){
+            return i > match[3] - 0;
+        },
+        nth: function(elem, i, match){
+            return match[3] - 0 == i;
+        },
+        eq: function(elem, i, match){
+            return match[3] - 0 == i;
+        }
+    },
+    filter: {
+        PSEUDO: function(elem, match, i, array){
+            var name = match[1], filter = Expr.filters[ name ];
+
+            if ( filter ) {
+                return filter( elem, i, match, array );
+            } else if ( name === "contains" ) {
+                return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
+            } else if ( name === "not" ) {
+                var not = match[3];
+
+                for ( var i = 0, l = not.length; i < l; i++ ) {
+                    if ( not[i] === elem ) {
+                        return false;
+                    }
+                }
+
+                return true;
+            }
+        },
+        CHILD: function(elem, match){
+            var type = match[1], node = elem;
+            switch (type) {
+                case 'only':
+                case 'first':
+                    while ( (node = node.previousSibling) )  {
+                        if ( node.nodeType === 1 ) return false;
+                    }
+                    if ( type == 'first') return true;
+                    node = elem;
+                case 'last':
+                    while ( (node = node.nextSibling) )  {
+                        if ( node.nodeType === 1 ) return false;
+                    }
+                    return true;
+                case 'nth':
+                    var first = match[2], last = match[3];
+
+                    if ( first == 1 && last == 0 ) {
+                        return true;
+                    }
+
+                    var doneName = match[0],
+                        parent = elem.parentNode;
+
+                    if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+                        var count = 0;
+                        for ( node = parent.firstChild; node; node = node.nextSibling ) {
+                            if ( node.nodeType === 1 ) {
+                                node.nodeIndex = ++count;
+                            }
+                        }
+                        parent.sizcache = doneName;
+                    }
+
+                    var diff = elem.nodeIndex - last;
+                    if ( first == 0 ) {
+                        return diff == 0;
+                    } else {
+                        return ( diff % first == 0 && diff / first >= 0 );
+                    }
+            }
+        },
+        ID: function(elem, match){
+            return elem.nodeType === 1 && elem.getAttribute("id") === match;
+        },
+        TAG: function(elem, match){
+            return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
+        },
+        CLASS: function(elem, match){
+            return (" " + (elem.className || elem.getAttribute("class")) + " ")
+                .indexOf( match ) > -1;
+        },
+        ATTR: function(elem, match){
+            var name = match[1],
+                result = Expr.attrHandle[ name ] ?
+                    Expr.attrHandle[ name ]( elem ) :
+                    elem[ name ] != null ?
+                        elem[ name ] :
+                        elem.getAttribute( name ),
+                value = result + "",
+                type = match[2],
+                check = match[4];
+
+            return result == null ?
+                type === "!=" :
+                type === "=" ?
+                value === check :
+                type === "*=" ?
+                value.indexOf(check) >= 0 :
+                type === "~=" ?
+                (" " + value + " ").indexOf(check) >= 0 :
+                !check ?
+                value && result !== false :
+                type === "!=" ?
+                value != check :
+                type === "^=" ?
+                value.indexOf(check) === 0 :
+                type === "$=" ?
+                value.substr(value.length - check.length) === check :
+                type === "|=" ?
+                value === check || value.substr(0, check.length + 1) === check + "-" :
+                false;
+        },
+        POS: function(elem, match, i, array){
+            var name = match[2], filter = Expr.setFilters[ name ];
+
+            if ( filter ) {
+                return filter( elem, i, match, array );
+            }
+        }
+    }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+    Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+    Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
+}
+
+var makeArray = function(array, results) {
+    array = Array.prototype.slice.call( array, 0 );
+
+    if ( results ) {
+        results.push.apply( results, array );
+        return results;
+    }
+
+    return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+    Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+// Provide a fallback method if it does not work
+} catch(e){
+    makeArray = function(array, results) {
+        var ret = results || [];
+
+        if ( toString.call(array) === "[object Array]" ) {
+            Array.prototype.push.apply( ret, array );
+        } else {
+            if ( typeof array.length === "number" ) {
+                for ( var i = 0, l = array.length; i < l; i++ ) {
+                    ret.push( array[i] );
+                }
+            } else {
+                for ( var i = 0; array[i]; i++ ) {
+                    ret.push( array[i] );
+                }
+            }
+        }
+
+        return ret;
+    };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+    sortOrder = function( a, b ) {
+        if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+            if ( a == b ) {
+                hasDuplicate = true;
+            }
+            return 0;
+        }
+
+        var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+        if ( ret === 0 ) {
+            hasDuplicate = true;
+        }
+        return ret;
+    };
+} else if ( "sourceIndex" in document.documentElement ) {
+    sortOrder = function( a, b ) {
+        if ( !a.sourceIndex || !b.sourceIndex ) {
+            if ( a == b ) {
+                hasDuplicate = true;
+            }
+            return 0;
+        }
+
+        var ret = a.sourceIndex - b.sourceIndex;
+        if ( ret === 0 ) {
+            hasDuplicate = true;
+        }
+        return ret;
+    };
+} else if ( document.createRange ) {
+    sortOrder = function( a, b ) {
+        if ( !a.ownerDocument || !b.ownerDocument ) {
+            if ( a == b ) {
+                hasDuplicate = true;
+            }
+            return 0;
+        }
+
+        var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+        aRange.setStart(a, 0);
+        aRange.setEnd(a, 0);
+        bRange.setStart(b, 0);
+        bRange.setEnd(b, 0);
+        var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+        if ( ret === 0 ) {
+            hasDuplicate = true;
+        }
+        return ret;
+    };
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+    // We're going to inject a fake input element with a specified name
+    var form = document.createElement("div"),
+        id = "script" + (new Date).getTime();
+    form.innerHTML = "<a name='" + id + "'/>";
+
+    // Inject it into the root element, check its status, and remove it quickly
+    var root = document.documentElement;
+    root.insertBefore( form, root.firstChild );
+
+    // The workaround has to do additional checks after a getElementById
+    // Which slows things down for other browsers (hence the branching)
+    if ( !!document.getElementById( id ) ) {
+        Expr.find.ID = function(match, context, isXML){
+            if ( typeof context.getElementById !== "undefined" && !isXML ) {
+                var m = context.getElementById(match[1]);
+                return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+            }
+        };
+
+        Expr.filter.ID = function(elem, match){
+            var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+            return elem.nodeType === 1 && node && node.nodeValue === match;
+        };
+    }
+
+    root.removeChild( form );
+    root = form = null; // release memory in IE
+})();
+
+(function(){
+    // Check to see if the browser returns only elements
+    // when doing getElementsByTagName("*")
+
+    // Create a fake element
+    var div = document.createElement("div");
+    div.appendChild( document.createComment("") );
+
+    // Make sure no comments are found
+    if ( div.getElementsByTagName("*").length > 0 ) {
+        Expr.find.TAG = function(match, context){
+            var results = context.getElementsByTagName(match[1]);
+
+            // Filter out possible comments
+            if ( match[1] === "*" ) {
+                var tmp = [];
+
+                for ( var i = 0; results[i]; i++ ) {
+                    if ( results[i].nodeType === 1 ) {
+                        tmp.push( results[i] );
+                    }
+                }
+
+                results = tmp;
+            }
+
+            return results;
+        };
+    }
+
+    // Check to see if an attribute returns normalized href attributes
+    div.innerHTML = "<a href='#'></a>";
+    if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+            div.firstChild.getAttribute("href") !== "#" ) {
+        Expr.attrHandle.href = function(elem){
+            return elem.getAttribute("href", 2);
+        };
+    }
+
+    div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) (function(){
+    var oldSizzle = Sizzle, div = document.createElement("div");
+    div.innerHTML = "<p class='TEST'></p>";
+
+    // Safari can't handle uppercase or unicode characters when
+    // in quirks mode.
+    if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+        return;
+    }
+
+    Sizzle = function(query, context, extra, seed){
+        context = context || document;
+
+        // Only use querySelectorAll on non-XML documents
+        // (ID selectors don't work in non-HTML documents)
+        if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+            try {
+                return makeArray( context.querySelectorAll(query), extra );
+            } catch(e){}
+        }
+
+        return oldSizzle(query, context, extra, seed);
+    };
+
+    for ( var prop in oldSizzle ) {
+        Sizzle[ prop ] = oldSizzle[ prop ];
+    }
+
+    div = null; // release memory in IE
+})();
+
+if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
+    var div = document.createElement("div");
+    div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+    // Opera can't find a second classname (in 9.6)
+    if ( div.getElementsByClassName("e").length === 0 )
+        return;
+
+    // Safari caches class attributes, doesn't catch changes (in 3.2)
+    div.lastChild.className = "e";
+
+    if ( div.getElementsByClassName("e").length === 1 )
+        return;
+
+    Expr.order.splice(1, 0, "CLASS");
+    Expr.find.CLASS = function(match, context, isXML) {
+        if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+            return context.getElementsByClassName(match[1]);
+        }
+    };
+
+    div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+    var sibDir = dir == "previousSibling" && !isXML;
+    for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+        var elem = checkSet[i];
+        if ( elem ) {
+            if ( sibDir && elem.nodeType === 1 ){
+                elem.sizcache = doneName;
+                elem.sizset = i;
+            }
+            elem = elem[dir];
+            var match = false;
+
+            while ( elem ) {
+                if ( elem.sizcache === doneName ) {
+                    match = checkSet[elem.sizset];
+                    break;
+                }
+
+                if ( elem.nodeType === 1 && !isXML ){
+                    elem.sizcache = doneName;
+                    elem.sizset = i;
+                }
+
+                if ( elem.nodeName === cur ) {
+                    match = elem;
+                    break;
+                }
+
+                elem = elem[dir];
+            }
+
+            checkSet[i] = match;
+        }
+    }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+    var sibDir = dir == "previousSibling" && !isXML;
+    for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+        var elem = checkSet[i];
+        if ( elem ) {
+            if ( sibDir && elem.nodeType === 1 ) {
+                elem.sizcache = doneName;
+                elem.sizset = i;
+            }
+            elem = elem[dir];
+            var match = false;
+
+            while ( elem ) {
+                if ( elem.sizcache === doneName ) {
+                    match = checkSet[elem.sizset];
+                    break;
+                }
+
+                if ( elem.nodeType === 1 ) {
+                    if ( !isXML ) {
+                        elem.sizcache = doneName;
+                        elem.sizset = i;
+                    }
+                    if ( typeof cur !== "string" ) {
+                        if ( elem === cur ) {
+                            match = true;
+                            break;
+                        }
+
+                    } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+                        match = elem;
+                        break;
+                    }
+                }
+
+                elem = elem[dir];
+            }
+
+            checkSet[i] = match;
+        }
+    }
+}
+
+var contains = document.compareDocumentPosition ?  function(a, b){
+    return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+    return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+    return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
+        !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
+};
+
+var posProcess = function(selector, context){
+    var tmpSet = [], later = "", match,
+        root = context.nodeType ? [context] : context;
+
+    // Position selectors must be done after the filter
+    // And so must :not(positional) so we move all PSEUDOs to the end
+    while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+        later += match[0];
+        selector = selector.replace( Expr.match.PSEUDO, "" );
+    }
+
+    selector = Expr.relative[selector] ? selector + "*" : selector;
+
+    for ( var i = 0, l = root.length; i < l; i++ ) {
+        Sizzle( selector, root[i], tmpSet );
+    }
+
+    return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+
+Firebug.Selector = Sizzle;
+
+/**#@-*/
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Inspector Module
+
+var ElementCache = Firebug.Lite.Cache.Element;
+
+var inspectorTS, inspectorTimer, isInspecting;
+
+Firebug.Inspector =
+{
+    create: function()
+    {
+        offlineFragment = Env.browser.document.createDocumentFragment();
+
+        createBoxModelInspector();
+        createOutlineInspector();
+    },
+
+    destroy: function()
+    {
+        destroyBoxModelInspector();
+        destroyOutlineInspector();
+
+        offlineFragment = null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Inspect functions
+
+    toggleInspect: function()
+    {
+        if (isInspecting)
+        {
+            this.stopInspecting();
+        }
+        else
+        {
+            Firebug.chrome.inspectButton.changeState("pressed");
+            this.startInspecting();
+        }
+    },
+
+    startInspecting: function()
+    {
+        isInspecting = true;
+
+        Firebug.chrome.selectPanel("HTML");
+
+        createInspectorFrame();
+
+        var size = Firebug.browser.getWindowScrollSize();
+
+        fbInspectFrame.style.width = size.width + "px";
+        fbInspectFrame.style.height = size.height + "px";
+
+        //addEvent(Firebug.browser.document.documentElement, "mousemove", Firebug.Inspector.onInspectingBody);
+
+        addEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting);
+        addEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick);
+    },
+
+    stopInspecting: function()
+    {
+        isInspecting = false;
+
+        if (outlineVisible) this.hideOutline();
+        removeEvent(fbInspectFrame, "mousemove", Firebug.Inspector.onInspecting);
+        removeEvent(fbInspectFrame, "mousedown", Firebug.Inspector.onInspectingClick);
+
+        destroyInspectorFrame();
+
+        Firebug.chrome.inspectButton.restore();
+
+        if (Firebug.chrome.type == "popup")
+            Firebug.chrome.node.focus();
+    },
+
+    onInspectingClick: function(e)
+    {
+        fbInspectFrame.style.display = "none";
+        var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
+        fbInspectFrame.style.display = "block";
+
+        // Avoid inspecting the outline, and the FirebugUI
+        var id = targ.id;
+        if (id && /^fbOutline\w$/.test(id)) return;
+        if (id == "FirebugUI") return;
+
+        // Avoid looking at text nodes in Opera
+        while (targ.nodeType != 1) targ = targ.parentNode;
+
+        //Firebug.Console.log(targ);
+        Firebug.Inspector.stopInspecting();
+    },
+
+    onInspecting: function(e)
+    {
+        if (new Date().getTime() - lastInspecting > 30)
+        {
+            fbInspectFrame.style.display = "none";
+            var targ = Firebug.browser.getElementFromPoint(e.clientX, e.clientY);
+            fbInspectFrame.style.display = "block";
+
+            // Avoid inspecting the outline, and the FirebugUI
+            var id = targ.id;
+            if (id && /^fbOutline\w$/.test(id)) return;
+            if (id == "FirebugUI") return;
+
+            // Avoid looking at text nodes in Opera
+            while (targ.nodeType != 1) targ = targ.parentNode;
+
+            if (targ.nodeName.toLowerCase() == "body") return;
+
+            //Firebug.Console.log(e.clientX, e.clientY, targ);
+            Firebug.Inspector.drawOutline(targ);
+
+            if (ElementCache(targ))
+            {
+                var target = ""+ElementCache.key(targ);
+                var lazySelect = function()
+                {
+                    inspectorTS = new Date().getTime();
+
+                    if (Firebug.HTML)
+                        Firebug.HTML.selectTreeNode(""+ElementCache.key(targ));
+                };
+
+                if (inspectorTimer)
+                {
+                    clearTimeout(inspectorTimer);
+                    inspectorTimer = null;
+                }
+
+                if (new Date().getTime() - inspectorTS > 200)
+                    setTimeout(lazySelect, 0);
+                else
+                    inspectorTimer = setTimeout(lazySelect, 300);
+            }
+
+            lastInspecting = new Date().getTime();
+        }
+    },
+
+    // TODO: xxxpedro remove this?
+    onInspectingBody: function(e)
+    {
+        if (new Date().getTime() - lastInspecting > 30)
+        {
+            var targ = e.target;
+
+            // Avoid inspecting the outline, and the FirebugUI
+            var id = targ.id;
+            if (id && /^fbOutline\w$/.test(id)) return;
+            if (id == "FirebugUI") return;
+
+            // Avoid looking at text nodes in Opera
+            while (targ.nodeType != 1) targ = targ.parentNode;
+
+            if (targ.nodeName.toLowerCase() == "body") return;
+
+            //Firebug.Console.log(e.clientX, e.clientY, targ);
+            Firebug.Inspector.drawOutline(targ);
+
+            if (ElementCache.has(targ))
+                FBL.Firebug.HTML.selectTreeNode(""+ElementCache.key(targ));
+
+            lastInspecting = new Date().getTime();
+        }
+    },
+
+    /**
+     *
+     *   llttttttrr
+     *   llttttttrr
+     *   ll      rr
+     *   ll      rr
+     *   llbbbbbbrr
+     *   llbbbbbbrr
+     */
+    drawOutline: function(el)
+    {
+        var border = 2;
+        var scrollbarSize = 17;
+
+        var windowSize = Firebug.browser.getWindowSize();
+        var scrollSize = Firebug.browser.getWindowScrollSize();
+        var scrollPosition = Firebug.browser.getWindowScrollPosition();
+
+        var box = Firebug.browser.getElementBox(el);
+
+        var top = box.top;
+        var left = box.left;
+        var height = box.height;
+        var width = box.width;
+
+        var freeHorizontalSpace = scrollPosition.left + windowSize.width - left - width -
+                (!isIE && scrollSize.height > windowSize.height ? // is *vertical* scrollbar visible
+                 scrollbarSize : 0);
+
+        var freeVerticalSpace = scrollPosition.top + windowSize.height - top - height -
+                (!isIE && scrollSize.width > windowSize.width ? // is *horizontal* scrollbar visible
+                scrollbarSize : 0);
+
+        var numVerticalBorders = freeVerticalSpace > 0 ? 2 : 1;
+
+        var o = outlineElements;
+        var style;
+
+        style = o.fbOutlineT.style;
+        style.top = top-border + "px";
+        style.left = left + "px";
+        style.height = border + "px";  // TODO: on initialize()
+        style.width = width + "px";
+
+        style = o.fbOutlineL.style;
+        style.top = top-border + "px";
+        style.left = left-border + "px";
+        style.height = height+ numVerticalBorders*border + "px";
+        style.width = border + "px";  // TODO: on initialize()
+
+        style = o.fbOutlineB.style;
+        if (freeVerticalSpace > 0)
+        {
+            style.top = top+height + "px";
+            style.left = left + "px";
+            style.width = width + "px";
+            //style.height = border + "px"; // TODO: on initialize() or worst case?
+        }
+        else
+        {
+            style.top = -2*border + "px";
+            style.left = -2*border + "px";
+            style.width = border + "px";
+            //style.height = border + "px";
+        }
+
+        style = o.fbOutlineR.style;
+        if (freeHorizontalSpace > 0)
+        {
+            style.top = top-border + "px";
+            style.left = left+width + "px";
+            style.height = height + numVerticalBorders*border + "px";
+            style.width = (freeHorizontalSpace < border ? freeHorizontalSpace : border) + "px";
+        }
+        else
+        {
+            style.top = -2*border + "px";
+            style.left = -2*border + "px";
+            style.height = border + "px";
+            style.width = border + "px";
+        }
+
+        if (!outlineVisible) this.showOutline();
+    },
+
+    hideOutline: function()
+    {
+        if (!outlineVisible) return;
+
+        for (var name in outline)
+            offlineFragment.appendChild(outlineElements[name]);
+
+        outlineVisible = false;
+    },
+
+    showOutline: function()
+    {
+        if (outlineVisible) return;
+
+        if (boxModelVisible) this.hideBoxModel();
+
+        for (var name in outline)
+            Firebug.browser.document.getElementsByTagName("body")[0].appendChild(outlineElements[name]);
+
+        outlineVisible = true;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Box Model
+
+    drawBoxModel: function(el)
+    {
+        // avoid error when the element is not attached a document
+        if (!el || !el.parentNode)
+            return;
+
+        var box = Firebug.browser.getElementBox(el);
+
+        var windowSize = Firebug.browser.getWindowSize();
+        var scrollPosition = Firebug.browser.getWindowScrollPosition();
+
+        // element may be occluded by the chrome, when in frame mode
+        var offsetHeight = Firebug.chrome.type == "frame" ? Firebug.context.persistedState.height : 0;
+
+        // if element box is not inside the viewport, don't draw the box model
+        if (box.top > scrollPosition.top + windowSize.height - offsetHeight ||
+            box.left > scrollPosition.left + windowSize.width ||
+            scrollPosition.top > box.top + box.height ||
+            scrollPosition.left > box.left + box.width )
+            return;
+
+        var top = box.top;
+        var left = box.left;
+        var height = box.height;
+        var width = box.width;
+
+        var margin = Firebug.browser.getMeasurementBox(el, "margin");
+        var padding = Firebug.browser.getMeasurementBox(el, "padding");
+        var border = Firebug.browser.getMeasurementBox(el, "border");
+
+        boxModelStyle.top = top - margin.top + "px";
+        boxModelStyle.left = left - margin.left + "px";
+        boxModelStyle.height = height + margin.top + margin.bottom + "px";
+        boxModelStyle.width = width + margin.left + margin.right + "px";
+
+        boxBorderStyle.top = margin.top + "px";
+        boxBorderStyle.left = margin.left + "px";
+        boxBorderStyle.height = height + "px";
+        boxBorderStyle.width = width + "px";
+
+        boxPaddingStyle.top = margin.top + border.top + "px";
+        boxPaddingStyle.left = margin.left + border.left + "px";
+        boxPaddingStyle.height = height - border.top - border.bottom + "px";
+        boxPaddingStyle.width = width - border.left - border.right + "px";
+
+        boxContentStyle.top = margin.top + border.top + padding.top + "px";
+        boxContentStyle.left = margin.left + border.left + padding.left + "px";
+        boxContentStyle.height = height - border.top - padding.top - padding.bottom - border.bottom + "px";
+        boxContentStyle.width = width - border.left - padding.left - padding.right - border.right + "px";
+
+        if (!boxModelVisible) this.showBoxModel();
+    },
+
+    hideBoxModel: function()
+    {
+        if (!boxModelVisible) return;
+
+        offlineFragment.appendChild(boxModel);
+        boxModelVisible = false;
+    },
+
+    showBoxModel: function()
+    {
+        if (boxModelVisible) return;
+
+        if (outlineVisible) this.hideOutline();
+
+        Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel);
+        boxModelVisible = true;
+    }
+
+};
+
+// ************************************************************************************************
+// Inspector Internals
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Shared variables
+
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// Internal variables
+
+var offlineFragment = null;
+
+var boxModelVisible = false;
+
+var boxModel, boxModelStyle,
+    boxMargin, boxMarginStyle,
+    boxBorder, boxBorderStyle,
+    boxPadding, boxPaddingStyle,
+    boxContent, boxContentStyle;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var resetStyle = "margin:0; padding:0; border:0; position:absolute; overflow:hidden; display:block;";
+var offscreenStyle = resetStyle + "top:-1234px; left:-1234px;";
+
+var inspectStyle = resetStyle + "z-index: 2147483500;";
+var inspectFrameStyle = resetStyle + "z-index: 2147483550; top:0; left:0; background:url(" +
+                        Env.Location.skinDir + "pixel_transparent.gif);";
+
+//if (Env.Options.enableTrace) inspectFrameStyle = resetStyle + "z-index: 2147483550; top: 0; left: 0; background: #ff0; opacity: 0.05; _filter: alpha(opacity=5);";
+
+var inspectModelOpacity = isIE ? "filter:alpha(opacity=80);" : "opacity:0.8;";
+var inspectModelStyle = inspectStyle + inspectModelOpacity;
+var inspectMarginStyle = inspectStyle + "background: #EDFF64; height:100%; width:100%;";
+var inspectBorderStyle = inspectStyle + "background: #666;";
+var inspectPaddingStyle = inspectStyle + "background: SlateBlue;";
+var inspectContentStyle = inspectStyle + "background: SkyBlue;";
+
+
+var outlineStyle = {
+    fbHorizontalLine: "background: #3875D7;height: 2px;",
+    fbVerticalLine: "background: #3875D7;width: 2px;"
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var lastInspecting = 0;
+var fbInspectFrame = null;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var outlineVisible = false;
+var outlineElements = {};
+var outline = {
+  "fbOutlineT": "fbHorizontalLine",
+  "fbOutlineL": "fbVerticalLine",
+  "fbOutlineB": "fbHorizontalLine",
+  "fbOutlineR": "fbVerticalLine"
+};
+
+
+var getInspectingTarget = function()
+{
+
+};
+
+// ************************************************************************************************
+// Section
+
+var createInspectorFrame = function createInspectorFrame()
+{
+    fbInspectFrame = createGlobalElement("div");
+    fbInspectFrame.id = "fbInspectFrame";
+    fbInspectFrame.firebugIgnore = true;
+    fbInspectFrame.style.cssText = inspectFrameStyle;
+    Firebug.browser.document.getElementsByTagName("body")[0].appendChild(fbInspectFrame);
+};
+
+var destroyInspectorFrame = function destroyInspectorFrame()
+{
+    if (fbInspectFrame)
+    {
+        Firebug.browser.document.getElementsByTagName("body")[0].removeChild(fbInspectFrame);
+        fbInspectFrame = null;
+    }
+};
+
+var createOutlineInspector = function createOutlineInspector()
+{
+    for (var name in outline)
+    {
+        var el = outlineElements[name] = createGlobalElement("div");
+        el.id = name;
+        el.firebugIgnore = true;
+        el.style.cssText = inspectStyle + outlineStyle[outline[name]];
+        offlineFragment.appendChild(el);
+    }
+};
+
+var destroyOutlineInspector = function destroyOutlineInspector()
+{
+    for (var name in outline)
+    {
+        var el = outlineElements[name];
+        el.parentNode.removeChild(el);
+    }
+};
+
+var createBoxModelInspector = function createBoxModelInspector()
+{
+    boxModel = createGlobalElement("div");
+    boxModel.id = "fbBoxModel";
+    boxModel.firebugIgnore = true;
+    boxModelStyle = boxModel.style;
+    boxModelStyle.cssText = inspectModelStyle;
+
+    boxMargin = createGlobalElement("div");
+    boxMargin.id = "fbBoxMargin";
+    boxMarginStyle = boxMargin.style;
+    boxMarginStyle.cssText = inspectMarginStyle;
+    boxModel.appendChild(boxMargin);
+
+    boxBorder = createGlobalElement("div");
+    boxBorder.id = "fbBoxBorder";
+    boxBorderStyle = boxBorder.style;
+    boxBorderStyle.cssText = inspectBorderStyle;
+    boxModel.appendChild(boxBorder);
+
+    boxPadding = createGlobalElement("div");
+    boxPadding.id = "fbBoxPadding";
+    boxPaddingStyle = boxPadding.style;
+    boxPaddingStyle.cssText = inspectPaddingStyle;
+    boxModel.appendChild(boxPadding);
+
+    boxContent = createGlobalElement("div");
+    boxContent.id = "fbBoxContent";
+    boxContentStyle = boxContent.style;
+    boxContentStyle.cssText = inspectContentStyle;
+    boxModel.appendChild(boxContent);
+
+    offlineFragment.appendChild(boxModel);
+};
+
+var destroyBoxModelInspector = function destroyBoxModelInspector()
+{
+    boxModel.parentNode.removeChild(boxModel);
+};
+
+// ************************************************************************************************
+// Section
+
+
+
+
+// ************************************************************************************************
+}});
+
+// Problems in IE
+// FIXED - eval return
+// FIXED - addEventListener problem in IE
+// FIXED doc.createRange?
+//
+// class reserved word
+// test all honza examples in IE6 and IE7
+
+
+/* See license.txt for terms of usage */
+
+( /** @scope s_domplate */ function() {
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+/** @class */
+FBL.DomplateTag = function DomplateTag(tagName)
+{
+    this.tagName = tagName;
+};
+
+/**
+ * @class
+ * @extends FBL.DomplateTag
+ */
+FBL.DomplateEmbed = function DomplateEmbed()
+{
+};
+
+/**
+ * @class
+ * @extends FBL.DomplateTag
+ */
+FBL.DomplateLoop = function DomplateLoop()
+{
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var DomplateTag = FBL.DomplateTag;
+var DomplateEmbed = FBL.DomplateEmbed;
+var DomplateLoop = FBL.DomplateLoop;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var womb = null;
+
+FBL.domplate = function()
+{
+    var lastSubject;
+    for (var i = 0; i < arguments.length; ++i)
+        lastSubject = lastSubject ? copyObject(lastSubject, arguments[i]) : arguments[i];
+
+    for (var name in lastSubject)
+    {
+        var val = lastSubject[name];
+        if (isTag(val))
+            val.tag.subject = lastSubject;
+    }
+
+    return lastSubject;
+};
+
+var domplate = FBL.domplate;
+
+FBL.domplate.context = function(context, fn)
+{
+    var lastContext = domplate.lastContext;
+    domplate.topContext = context;
+    fn.apply(context);
+    domplate.topContext = lastContext;
+};
+
+FBL.TAG = function()
+{
+    var embed = new DomplateEmbed();
+    return embed.merge(arguments);
+};
+
+FBL.FOR = function()
+{
+    var loop = new DomplateLoop();
+    return loop.merge(arguments);
+};
+
+FBL.DomplateTag.prototype =
+{
+    merge: function(args, oldTag)
+    {
+        if (oldTag)
+            this.tagName = oldTag.tagName;
+
+        this.context = oldTag ? oldTag.context : null;
+        this.subject = oldTag ? oldTag.subject : null;
+        this.attrs = oldTag ? copyObject(oldTag.attrs) : {};
+        this.classes = oldTag ? copyObject(oldTag.classes) : {};
+        this.props = oldTag ? copyObject(oldTag.props) : null;
+        this.listeners = oldTag ? copyArray(oldTag.listeners) : null;
+        this.children = oldTag ? copyArray(oldTag.children) : [];
+        this.vars = oldTag ? copyArray(oldTag.vars) : [];
+
+        var attrs = args.length ? args[0] : null;
+        var hasAttrs = typeof(attrs) == "object" && !isTag(attrs);
+
+        this.children = [];
+
+        if (domplate.topContext)
+            this.context = domplate.topContext;
+
+        if (args.length)
+            parseChildren(args, hasAttrs ? 1 : 0, this.vars, this.children);
+
+        if (hasAttrs)
+            this.parseAttrs(attrs);
+
+        return creator(this, DomplateTag);
+    },
+
+    parseAttrs: function(args)
+    {
+        for (var name in args)
+        {
+            var val = parseValue(args[name]);
+            readPartNames(val, this.vars);
+
+            if (name.indexOf("on") == 0)
+            {
+                var eventName = name.substr(2);
+                if (!this.listeners)
+                    this.listeners = [];
+                this.listeners.push(eventName, val);
+            }
+            else if (name.indexOf("_") == 0)
+            {
+                var propName = name.substr(1);
+                if (!this.props)
+                    this.props = {};
+                this.props[propName] = val;
+            }
+            else if (name.indexOf("$") == 0)
+            {
+                var className = name.substr(1);
+                if (!this.classes)
+                    this.classes = {};
+                this.classes[className] = val;
+            }
+            else
+            {
+                if (name == "class" && this.attrs.hasOwnProperty(name) )
+                    this.attrs[name] += " " + val;
+                else
+                    this.attrs[name] = val;
+            }
+        }
+    },
+
+    compile: function()
+    {
+        if (this.renderMarkup)
+            return;
+
+        this.compileMarkup();
+        this.compileDOM();
+
+        //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderMarkup: ", this.renderMarkup);
+        //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate renderDOM:", this.renderDOM);
+        //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate domArgs:", this.domArgs);
+    },
+
+    compileMarkup: function()
+    {
+        this.markupArgs = [];
+        var topBlock = [], topOuts = [], blocks = [], info = {args: this.markupArgs, argIndex: 0};
+
+        this.generateMarkup(topBlock, topOuts, blocks, info);
+        this.addCode(topBlock, topOuts, blocks);
+
+        var fnBlock = ['r=(function (__code__, __context__, __in__, __out__'];
+        for (var i = 0; i < info.argIndex; ++i)
+            fnBlock.push(', s', i);
+        fnBlock.push(') {');
+
+        if (this.subject)
+            fnBlock.push('with (this) {');
+        if (this.context)
+            fnBlock.push('with (__context__) {');
+        fnBlock.push('with (__in__) {');
+
+        fnBlock.push.apply(fnBlock, blocks);
+
+        if (this.subject)
+            fnBlock.push('}');
+        if (this.context)
+            fnBlock.push('}');
+
+        fnBlock.push('}})');
+
+        function __link__(tag, code, outputs, args)
+        {
+            if (!tag || !tag.tag)
+                return;
+
+            tag.tag.compile();
+
+            var tagOutputs = [];
+            var markupArgs = [code, tag.tag.context, args, tagOutputs];
+            markupArgs.push.apply(markupArgs, tag.tag.markupArgs);
+            tag.tag.renderMarkup.apply(tag.tag.subject, markupArgs);
+
+            outputs.push(tag);
+            outputs.push(tagOutputs);
+        }
+
+        function __escape__(value)
+        {
+            function replaceChars(ch)
+            {
+                switch (ch)
+                {
+                    case "<":
+                        return "&lt;";
+                    case ">":
+                        return "&gt;";
+                    case "&":
+                        return "&amp;";
+                    case "'":
+                        return "&#39;";
+                    case '"':
+                        return "&quot;";
+                }
+                return "?";
+            };
+            return String(value).replace(/[<>&"']/g, replaceChars);
+        }
+
+        function __loop__(iter, outputs, fn)
+        {
+            var iterOuts = [];
+            outputs.push(iterOuts);
+
+            if (iter instanceof Array)
+                iter = new ArrayIterator(iter);
+
+            try
+            {
+                while (1)
+                {
+                    var value = iter.next();
+                    var itemOuts = [0,0];
+                    iterOuts.push(itemOuts);
+                    fn.apply(this, [value, itemOuts]);
+                }
+            }
+            catch (exc)
+            {
+                if (exc != StopIteration)
+                    throw exc;
+            }
+        }
+
+        var js = fnBlock.join("");
+        var r = null;
+        eval(js);
+        this.renderMarkup = r;
+    },
+
+    getVarNames: function(args)
+    {
+        if (this.vars)
+            args.push.apply(args, this.vars);
+
+        for (var i = 0; i < this.children.length; ++i)
+        {
+            var child = this.children[i];
+            if (isTag(child))
+                child.tag.getVarNames(args);
+            else if (child instanceof Parts)
+            {
+                for (var i = 0; i < child.parts.length; ++i)
+                {
+                    if (child.parts[i] instanceof Variable)
+                    {
+                        var name = child.parts[i].name;
+                        var names = name.split(".");
+                        args.push(names[0]);
+                    }
+                }
+            }
+        }
+    },
+
+    generateMarkup: function(topBlock, topOuts, blocks, info)
+    {
+        topBlock.push(',"<', this.tagName, '"');
+
+        for (var name in this.attrs)
+        {
+            if (name != "class")
+            {
+                var val = this.attrs[name];
+                topBlock.push(', " ', name, '=\\""');
+                addParts(val, ',', topBlock, info, true);
+                topBlock.push(', "\\""');
+            }
+        }
+
+        if (this.listeners)
+        {
+            for (var i = 0; i < this.listeners.length; i += 2)
+                readPartNames(this.listeners[i+1], topOuts);
+        }
+
+        if (this.props)
+        {
+            for (var name in this.props)
+                readPartNames(this.props[name], topOuts);
+        }
+
+        if ( this.attrs.hasOwnProperty("class") || this.classes)
+        {
+            topBlock.push(', " class=\\""');
+            if (this.attrs.hasOwnProperty("class"))
+                addParts(this.attrs["class"], ',', topBlock, info, true);
+              topBlock.push(', " "');
+            for (var name in this.classes)
+            {
+                topBlock.push(', (');
+                addParts(this.classes[name], '', topBlock, info);
+                topBlock.push(' ? "', name, '" + " " : "")');
+            }
+            topBlock.push(', "\\""');
+        }
+        topBlock.push(',">"');
+
+        this.generateChildMarkup(topBlock, topOuts, blocks, info);
+        topBlock.push(',"</', this.tagName, '>"');
+    },
+
+    generateChildMarkup: function(topBlock, topOuts, blocks, info)
+    {
+        for (var i = 0; i < this.children.length; ++i)
+        {
+            var child = this.children[i];
+            if (isTag(child))
+                child.tag.generateMarkup(topBlock, topOuts, blocks, info);
+            else
+                addParts(child, ',', topBlock, info, true);
+        }
+    },
+
+    addCode: function(topBlock, topOuts, blocks)
+    {
+        if (topBlock.length)
+            blocks.push('__code__.push(""', topBlock.join(""), ');');
+        if (topOuts.length)
+            blocks.push('__out__.push(', topOuts.join(","), ');');
+        topBlock.splice(0, topBlock.length);
+        topOuts.splice(0, topOuts.length);
+    },
+
+    addLocals: function(blocks)
+    {
+        var varNames = [];
+        this.getVarNames(varNames);
+
+        var map = {};
+        for (var i = 0; i < varNames.length; ++i)
+        {
+            var name = varNames[i];
+            if ( map.hasOwnProperty(name) )
+                continue;
+
+            map[name] = 1;
+            var names = name.split(".");
+            blocks.push('var ', names[0] + ' = ' + '__in__.' + names[0] + ';');
+        }
+    },
+
+    compileDOM: function()
+    {
+        var path = [];
+        var blocks = [];
+        this.domArgs = [];
+        path.embedIndex = 0;
+        path.loopIndex = 0;
+        path.staticIndex = 0;
+        path.renderIndex = 0;
+        var nodeCount = this.generateDOM(path, blocks, this.domArgs);
+
+        var fnBlock = ['r=(function (root, context, o'];
+
+        for (var i = 0; i < path.staticIndex; ++i)
+            fnBlock.push(', ', 's'+i);
+
+        for (var i = 0; i < path.renderIndex; ++i)
+            fnBlock.push(', ', 'd'+i);
+
+        fnBlock.push(') {');
+        for (var i = 0; i < path.loopIndex; ++i)
+            fnBlock.push('var l', i, ' = 0;');
+        for (var i = 0; i < path.embedIndex; ++i)
+            fnBlock.push('var e', i, ' = 0;');
+
+        if (this.subject)
+            fnBlock.push('with (this) {');
+        if (this.context)
+            fnBlock.push('with (context) {');
+
+        fnBlock.push(blocks.join(""));
+
+        if (this.subject)
+            fnBlock.push('}');
+        if (this.context)
+            fnBlock.push('}');
+
+        fnBlock.push('return ', nodeCount, ';');
+        fnBlock.push('})');
+
+        function __bind__(object, fn)
+        {
+            return function(event) { return fn.apply(object, [event]); };
+        }
+
+        function __link__(node, tag, args)
+        {
+            if (!tag || !tag.tag)
+                return;
+
+            tag.tag.compile();
+
+            var domArgs = [node, tag.tag.context, 0];
+            domArgs.push.apply(domArgs, tag.tag.domArgs);
+            domArgs.push.apply(domArgs, args);
+            //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate__link__ domArgs:", domArgs);
+            return tag.tag.renderDOM.apply(tag.tag.subject, domArgs);
+        }
+
+        var self = this;
+        function __loop__(iter, fn)
+        {
+            var nodeCount = 0;
+            for (var i = 0; i < iter.length; ++i)
+            {
+                iter[i][0] = i;
+                iter[i][1] = nodeCount;
+                nodeCount += fn.apply(this, iter[i]);
+                //if (FBTrace.DBG_DOM) FBTrace.sysout("nodeCount", nodeCount);
+            }
+            return nodeCount;
+        }
+
+        function __path__(parent, offset)
+        {
+            //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate __path__ offset: "+ offset+"\n");
+            var root = parent;
+
+            for (var i = 2; i < arguments.length; ++i)
+            {
+                var index = arguments[i];
+                if (i == 3)
+                    index += offset;
+
+                if (index == -1)
+                    parent = parent.parentNode;
+                else
+                    parent = parent.childNodes[index];
+            }
+
+            //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate: "+arguments[2]+", root: "+ root+", parent: "+ parent+"\n");
+            return parent;
+        }
+
+        var js = fnBlock.join("");
+        //if (FBTrace.DBG_DOM) FBTrace.sysout(js.replace(/(\;|\{)/g, "$1\n"));
+        var r = null;
+        eval(js);
+        this.renderDOM = r;
+    },
+
+    generateDOM: function(path, blocks, args)
+    {
+        if (this.listeners || this.props)
+            this.generateNodePath(path, blocks);
+
+        if (this.listeners)
+        {
+            for (var i = 0; i < this.listeners.length; i += 2)
+            {
+                var val = this.listeners[i+1];
+                var arg = generateArg(val, path, args);
+                //blocks.push('node.addEventListener("', this.listeners[i], '", __bind__(this, ', arg, '), false);');
+                blocks.push('addEvent(node, "', this.listeners[i], '", __bind__(this, ', arg, '), false);');
+            }
+        }
+
+        if (this.props)
+        {
+            for (var name in this.props)
+            {
+                var val = this.props[name];
+                var arg = generateArg(val, path, args);
+                blocks.push('node.', name, ' = ', arg, ';');
+            }
+        }
+
+        this.generateChildDOM(path, blocks, args);
+        return 1;
+    },
+
+    generateNodePath: function(path, blocks)
+    {
+        blocks.push("var node = __path__(root, o");
+        for (var i = 0; i < path.length; ++i)
+            blocks.push(",", path[i]);
+        blocks.push(");");
+    },
+
+    generateChildDOM: function(path, blocks, args)
+    {
+        path.push(0);
+        for (var i = 0; i < this.children.length; ++i)
+        {
+            var child = this.children[i];
+            if (isTag(child))
+                path[path.length-1] += '+' + child.tag.generateDOM(path, blocks, args);
+            else
+                path[path.length-1] += '+1';
+        }
+        path.pop();
+    }
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+FBL.DomplateEmbed.prototype = copyObject(FBL.DomplateTag.prototype,
+/** @lends FBL.DomplateEmbed.prototype */
+{
+    merge: function(args, oldTag)
+    {
+        this.value = oldTag ? oldTag.value : parseValue(args[0]);
+        this.attrs = oldTag ? oldTag.attrs : {};
+        this.vars = oldTag ? copyArray(oldTag.vars) : [];
+
+        var attrs = args[1];
+        for (var name in attrs)
+        {
+            var val = parseValue(attrs[name]);
+            this.attrs[name] = val;
+            readPartNames(val, this.vars);
+        }
+
+        return creator(this, DomplateEmbed);
+    },
+
+    getVarNames: function(names)
+    {
+        if (this.value instanceof Parts)
+            names.push(this.value.parts[0].name);
+
+        if (this.vars)
+            names.push.apply(names, this.vars);
+    },
+
+    generateMarkup: function(topBlock, topOuts, blocks, info)
+    {
+        this.addCode(topBlock, topOuts, blocks);
+
+        blocks.push('__link__(');
+        addParts(this.value, '', blocks, info);
+        blocks.push(', __code__, __out__, {');
+
+        var lastName = null;
+        for (var name in this.attrs)
+        {
+            if (lastName)
+                blocks.push(',');
+            lastName = name;
+
+            var val = this.attrs[name];
+            blocks.push('"', name, '":');
+            addParts(val, '', blocks, info);
+        }
+
+        blocks.push('});');
+        //this.generateChildMarkup(topBlock, topOuts, blocks, info);
+    },
+
+    generateDOM: function(path, blocks, args)
+    {
+        var embedName = 'e'+path.embedIndex++;
+
+        this.generateNodePath(path, blocks);
+
+        var valueName = 'd' + path.renderIndex++;
+        var argsName = 'd' + path.renderIndex++;
+        blocks.push(embedName + ' = __link__(node, ', valueName, ', ', argsName, ');');
+
+        return embedName;
+    }
+});
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+FBL.DomplateLoop.prototype = copyObject(FBL.DomplateTag.prototype,
+/** @lends FBL.DomplateLoop.prototype */
+{
+    merge: function(args, oldTag)
+    {
+        this.varName = oldTag ? oldTag.varName : args[0];
+        this.iter = oldTag ? oldTag.iter : parseValue(args[1]);
+        this.vars = [];
+
+        this.children = oldTag ? copyArray(oldTag.children) : [];
+
+        var offset = Math.min(args.length, 2);
+        parseChildren(args, offset, this.vars, this.children);
+
+        return creator(this, DomplateLoop);
+    },
+
+    getVarNames: function(names)
+    {
+        if (this.iter instanceof Parts)
+            names.push(this.iter.parts[0].name);
+
+        DomplateTag.prototype.getVarNames.apply(this, [names]);
+    },
+
+    generateMarkup: function(topBlock, topOuts, blocks, info)
+    {
+        this.addCode(topBlock, topOuts, blocks);
+
+        var iterName;
+        if (this.iter instanceof Parts)
+        {
+            var part = this.iter.parts[0];
+            iterName = part.name;
+
+            if (part.format)
+            {
+                for (var i = 0; i < part.format.length; ++i)
+                    iterName = part.format[i] + "(" + iterName + ")";
+            }
+        }
+        else
+            iterName = this.iter;
+
+        blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(', this.varName, ', __out__) {');
+        this.generateChildMarkup(topBlock, topOuts, blocks, info);
+        this.addCode(topBlock, topOuts, blocks);
+        blocks.push('}]);');
+    },
+
+    generateDOM: function(path, blocks, args)
+    {
+        var iterName = 'd'+path.renderIndex++;
+        var counterName = 'i'+path.loopIndex;
+        var loopName = 'l'+path.loopIndex++;
+
+        if (!path.length)
+            path.push(-1, 0);
+
+        var preIndex = path.renderIndex;
+        path.renderIndex = 0;
+
+        var nodeCount = 0;
+
+        var subBlocks = [];
+        var basePath = path[path.length-1];
+        for (var i = 0; i < this.children.length; ++i)
+        {
+            path[path.length-1] = basePath+'+'+loopName+'+'+nodeCount;
+
+            var child = this.children[i];
+            if (isTag(child))
+                nodeCount += '+' + child.tag.generateDOM(path, subBlocks, args);
+            else
+                nodeCount += '+1';
+        }
+
+        path[path.length-1] = basePath+'+'+loopName;
+
+        blocks.push(loopName,' = __loop__.apply(this, [', iterName, ', function(', counterName,',',loopName);
+        for (var i = 0; i < path.renderIndex; ++i)
+            blocks.push(',d'+i);
+        blocks.push(') {');
+        blocks.push(subBlocks.join(""));
+        blocks.push('return ', nodeCount, ';');
+        blocks.push('}]);');
+
+        path.renderIndex = preIndex;
+
+        return loopName;
+    }
+});
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+/** @class */
+function Variable(name, format)
+{
+    this.name = name;
+    this.format = format;
+}
+
+/** @class */
+function Parts(parts)
+{
+    this.parts = parts;
+}
+
+// ************************************************************************************************
+
+function parseParts(str)
+{
+    var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g;
+    var index = 0;
+    var parts = [];
+
+    var m;
+    while (m = re.exec(str))
+    {
+        var pre = str.substr(index, (re.lastIndex-m[0].length)-index);
+        if (pre)
+            parts.push(pre);
+
+        var expr = m[1].split("|");
+        parts.push(new Variable(expr[0], expr.slice(1)));
+        index = re.lastIndex;
+    }
+
+    if (!index)
+        return str;
+
+    var post = str.substr(index);
+    if (post)
+        parts.push(post);
+
+    return new Parts(parts);
+}
+
+function parseValue(val)
+{
+    return typeof(val) == 'string' ? parseParts(val) : val;
+}
+
+function parseChildren(args, offset, vars, children)
+{
+    for (var i = offset; i < args.length; ++i)
+    {
+        var val = parseValue(args[i]);
+        children.push(val);
+        readPartNames(val, vars);
+    }
+}
+
+function readPartNames(val, vars)
+{
+    if (val instanceof Parts)
+    {
+        for (var i = 0; i < val.parts.length; ++i)
+        {
+            var part = val.parts[i];
+            if (part instanceof Variable)
+                vars.push(part.name);
+        }
+    }
+}
+
+function generateArg(val, path, args)
+{
+    if (val instanceof Parts)
+    {
+        var vals = [];
+        for (var i = 0; i < val.parts.length; ++i)
+        {
+            var part = val.parts[i];
+            if (part instanceof Variable)
+            {
+                var varName = 'd'+path.renderIndex++;
+                if (part.format)
+                {
+                    for (var j = 0; j < part.format.length; ++j)
+                        varName = part.format[j] + '(' + varName + ')';
+                }
+
+                vals.push(varName);
+            }
+            else
+                vals.push('"'+part.replace(/"/g, '\\"')+'"');
+        }
+
+        return vals.join('+');
+    }
+    else
+    {
+        args.push(val);
+        return 's' + path.staticIndex++;
+    }
+}
+
+function addParts(val, delim, block, info, escapeIt)
+{
+    var vals = [];
+    if (val instanceof Parts)
+    {
+        for (var i = 0; i < val.parts.length; ++i)
+        {
+            var part = val.parts[i];
+            if (part instanceof Variable)
+            {
+                var partName = part.name;
+                if (part.format)
+                {
+                    for (var j = 0; j < part.format.length; ++j)
+                        partName = part.format[j] + "(" + partName + ")";
+                }
+
+                if (escapeIt)
+                    vals.push("__escape__(" + partName + ")");
+                else
+                    vals.push(partName);
+            }
+            else
+                vals.push('"'+ part + '"');
+        }
+    }
+    else if (isTag(val))
+    {
+        info.args.push(val);
+        vals.push('s'+info.argIndex++);
+    }
+    else
+        vals.push('"'+ val + '"');
+
+    var parts = vals.join(delim);
+    if (parts)
+        block.push(delim, parts);
+}
+
+function isTag(obj)
+{
+    return (typeof(obj) == "function" || obj instanceof Function) && !!obj.tag;
+}
+
+function creator(tag, cons)
+{
+    var fn = new Function(
+        "var tag = arguments.callee.tag;" +
+        "var cons = arguments.callee.cons;" +
+        "var newTag = new cons();" +
+        "return newTag.merge(arguments, tag);");
+
+    fn.tag = tag;
+    fn.cons = cons;
+    extend(fn, Renderer);
+
+    return fn;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+function copyArray(oldArray)
+{
+    var ary = [];
+    if (oldArray)
+        for (var i = 0; i < oldArray.length; ++i)
+            ary.push(oldArray[i]);
+   return ary;
+}
+
+function copyObject(l, r)
+{
+    var m = {};
+    extend(m, l);
+    extend(m, r);
+    return m;
+}
+
+function extend(l, r)
+{
+    for (var n in r)
+        l[n] = r[n];
+}
+
+function addEvent(object, name, handler)
+{
+    if (document.all)
+        object.attachEvent("on"+name, handler);
+    else
+        object.addEventListener(name, handler, false);
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+/** @class */
+function ArrayIterator(array)
+{
+    var index = -1;
+
+    this.next = function()
+    {
+        if (++index >= array.length)
+            throw StopIteration;
+
+        return array[index];
+    };
+}
+
+/** @class */
+function StopIteration() {}
+
+FBL.$break = function()
+{
+    throw StopIteration;
+};
+
+// ************************************************************************************************
+
+/** @namespace */
+var Renderer =
+{
+    renderHTML: function(args, outputs, self)
+    {
+        var code = [];
+        var markupArgs = [code, this.tag.context, args, outputs];
+        markupArgs.push.apply(markupArgs, this.tag.markupArgs);
+        this.tag.renderMarkup.apply(self ? self : this.tag.subject, markupArgs);
+        return code.join("");
+    },
+
+    insertRows: function(args, before, self)
+    {
+        this.tag.compile();
+
+        var outputs = [];
+        var html = this.renderHTML(args, outputs, self);
+
+        var doc = before.ownerDocument;
+        var div = doc.createElement("div");
+        div.innerHTML = "<table><tbody>"+html+"</tbody></table>";
+
+        var tbody = div.firstChild.firstChild;
+        var parent = before.tagName == "TR" ? before.parentNode : before;
+        var after = before.tagName == "TR" ? before.nextSibling : null;
+
+        var firstRow = tbody.firstChild, lastRow;
+        while (tbody.firstChild)
+        {
+            lastRow = tbody.firstChild;
+            if (after)
+                parent.insertBefore(lastRow, after);
+            else
+                parent.appendChild(lastRow);
+        }
+
+        var offset = 0;
+        if (before.tagName == "TR")
+        {
+            var node = firstRow.parentNode.firstChild;
+            for (; node && node != firstRow; node = node.nextSibling)
+                ++offset;
+        }
+
+        var domArgs = [firstRow, this.tag.context, offset];
+        domArgs.push.apply(domArgs, this.tag.domArgs);
+        domArgs.push.apply(domArgs, outputs);
+
+        this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+        return [firstRow, lastRow];
+    },
+
+    insertBefore: function(args, before, self)
+    {
+        return this.insertNode(args, before.ownerDocument, before, false, self);
+    },
+
+    insertAfter: function(args, after, self)
+    {
+        return this.insertNode(args, after.ownerDocument, after, true, self);
+    },
+
+    insertNode: function(args, doc, element, isAfter, self)
+    {
+        if (!args)
+            args = {};
+
+        this.tag.compile();
+
+        var outputs = [];
+        var html = this.renderHTML(args, outputs, self);
+
+        //if (FBTrace.DBG_DOM)
+        //    FBTrace.sysout("domplate.insertNode html: "+html+"\n");
+
+        var doc = element.ownerDocument;
+        if (!womb || womb.ownerDocument != doc)
+            womb = doc.createElement("div");
+
+        womb.innerHTML = html;
+
+        var root = womb.firstChild;
+        if (isAfter)
+        {
+            while (womb.firstChild)
+                if (element.nextSibling)
+                    element.parentNode.insertBefore(womb.firstChild, element.nextSibling);
+                else
+                    element.parentNode.appendChild(womb.firstChild);
+        }
+        else
+        {
+            while (womb.lastChild)
+                element.parentNode.insertBefore(womb.lastChild, element);
+        }
+
+        var domArgs = [root, this.tag.context, 0];
+        domArgs.push.apply(domArgs, this.tag.domArgs);
+        domArgs.push.apply(domArgs, outputs);
+
+        //if (FBTrace.DBG_DOM)
+        //    FBTrace.sysout("domplate.insertNode domArgs:", domArgs);
+        this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+
+        return root;
+    },
+    /**/
+
+    /*
+    insertAfter: function(args, before, self)
+    {
+        this.tag.compile();
+
+        var outputs = [];
+        var html = this.renderHTML(args, outputs, self);
+
+        var doc = before.ownerDocument;
+        if (!womb || womb.ownerDocument != doc)
+            womb = doc.createElement("div");
+
+        womb.innerHTML = html;
+
+        var root = womb.firstChild;
+        while (womb.firstChild)
+            if (before.nextSibling)
+                before.parentNode.insertBefore(womb.firstChild, before.nextSibling);
+            else
+                before.parentNode.appendChild(womb.firstChild);
+
+        var domArgs = [root, this.tag.context, 0];
+        domArgs.push.apply(domArgs, this.tag.domArgs);
+        domArgs.push.apply(domArgs, outputs);
+
+        this.tag.renderDOM.apply(self ? self : (this.tag.subject ? this.tag.subject : null),
+            domArgs);
+
+        return root;
+    },
+    /**/
+
+    replace: function(args, parent, self)
+    {
+        this.tag.compile();
+
+        var outputs = [];
+        var html = this.renderHTML(args, outputs, self);
+
+        var root;
+        if (parent.nodeType == 1)
+        {
+            parent.innerHTML = html;
+            root = parent.firstChild;
+        }
+        else
+        {
+            if (!parent || parent.nodeType != 9)
+                parent = document;
+
+            if (!womb || womb.ownerDocument != parent)
+                womb = parent.createElement("div");
+            womb.innerHTML = html;
+
+            root = womb.firstChild;
+            //womb.removeChild(root);
+        }
+
+        var domArgs = [root, this.tag.context, 0];
+        domArgs.push.apply(domArgs, this.tag.domArgs);
+        domArgs.push.apply(domArgs, outputs);
+        this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+
+        return root;
+    },
+
+    append: function(args, parent, self)
+    {
+        this.tag.compile();
+
+        var outputs = [];
+        var html = this.renderHTML(args, outputs, self);
+        //if (FBTrace.DBG_DOM) FBTrace.sysout("domplate.append html: "+html+"\n");
+
+        if (!womb || womb.ownerDocument != parent.ownerDocument)
+            womb = parent.ownerDocument.createElement("div");
+        womb.innerHTML = html;
+
+        // TODO: xxxpedro domplate port to Firebug
+        var root = womb.firstChild;
+        while (womb.firstChild)
+            parent.appendChild(womb.firstChild);
+
+        // clearing element reference to avoid reference error in IE8 when switching contexts
+        womb = null;
+
+        var domArgs = [root, this.tag.context, 0];
+        domArgs.push.apply(domArgs, this.tag.domArgs);
+        domArgs.push.apply(domArgs, outputs);
+
+        //if (FBTrace.DBG_DOM) FBTrace.dumpProperties("domplate append domArgs:", domArgs);
+        this.tag.renderDOM.apply(self ? self : this.tag.subject, domArgs);
+
+        return root;
+    }
+};
+
+// ************************************************************************************************
+
+function defineTags()
+{
+    for (var i = 0; i < arguments.length; ++i)
+    {
+        var tagName = arguments[i];
+        var fn = new Function("var newTag = new arguments.callee.DomplateTag('"+tagName+"'); return newTag.merge(arguments);");
+        fn.DomplateTag = DomplateTag;
+
+        var fnName = tagName.toUpperCase();
+        FBL[fnName] = fn;
+    }
+}
+
+defineTags(
+    "a", "button", "br", "canvas", "code", "col", "colgroup", "div", "fieldset", "form", "h1", "h2", "h3", "hr",
+     "img", "input", "label", "legend", "li", "ol", "optgroup", "option", "p", "pre", "select",
+    "span", "strong", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "tr", "tt", "ul", "iframe"
+);
+
+})();
+
+
+/* See license.txt for terms of usage */
+
+var FirebugReps = FBL.ns(function() { with (FBL) {
+
+
+// ************************************************************************************************
+// Common Tags
+
+var OBJECTBOX = this.OBJECTBOX =
+    SPAN({"class": "objectBox objectBox-$className"});
+
+var OBJECTBLOCK = this.OBJECTBLOCK =
+    DIV({"class": "objectBox objectBox-$className"});
+
+var OBJECTLINK = this.OBJECTLINK = isIE6 ? // IE6 object link representation
+    A({
+        "class": "objectLink objectLink-$className a11yFocus",
+        href: "javascript:void(0)",
+        // workaround to show XPath (a better approach would use the tooltip on mouseover,
+        // so the XPath information would be calculated dynamically, but we need to create
+        // a tooltip class/wrapper around Menu or InfoTip)
+        title: "$object|FBL.getElementXPath",
+        _repObject: "$object"
+    })
+    : // Other browsers
+    A({
+        "class": "objectLink objectLink-$className a11yFocus",
+        // workaround to show XPath (a better approach would use the tooltip on mouseover,
+        // so the XPath information would be calculated dynamically, but we need to create
+        // a tooltip class/wrapper around Menu or InfoTip)
+        title: "$object|FBL.getElementXPath",
+        _repObject: "$object"
+    });
+
+
+// ************************************************************************************************
+
+this.Undefined = domplate(Firebug.Rep,
+{
+    tag: OBJECTBOX("undefined"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "undefined",
+
+    supportsObject: function(object, type)
+    {
+        return type == "undefined";
+    }
+});
+
+// ************************************************************************************************
+
+this.Null = domplate(Firebug.Rep,
+{
+    tag: OBJECTBOX("null"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "null",
+
+    supportsObject: function(object, type)
+    {
+        return object == null;
+    }
+});
+
+// ************************************************************************************************
+
+this.Nada = domplate(Firebug.Rep,
+{
+    tag: SPAN(""),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "nada"
+});
+
+// ************************************************************************************************
+
+this.Number = domplate(Firebug.Rep,
+{
+    tag: OBJECTBOX("$object"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "number",
+
+    supportsObject: function(object, type)
+    {
+        return type == "boolean" || type == "number";
+    }
+});
+
+// ************************************************************************************************
+
+this.String = domplate(Firebug.Rep,
+{
+    tag: OBJECTBOX("&quot;$object&quot;"),
+
+    shortTag: OBJECTBOX("&quot;$object|cropString&quot;"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "string",
+
+    supportsObject: function(object, type)
+    {
+        return type == "string";
+    }
+});
+
+// ************************************************************************************************
+
+this.Text = domplate(Firebug.Rep,
+{
+    tag: OBJECTBOX("$object"),
+
+    shortTag: OBJECTBOX("$object|cropString"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "text"
+});
+
+// ************************************************************************************************
+
+this.Caption = domplate(Firebug.Rep,
+{
+    tag: SPAN({"class": "caption"}, "$object")
+});
+
+// ************************************************************************************************
+
+this.Warning = domplate(Firebug.Rep,
+{
+    tag: DIV({"class": "warning focusRow", role : 'listitem'}, "$object|STR")
+});
+
+// ************************************************************************************************
+
+this.Func = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK("$object|summarizeFunction"),
+
+    summarizeFunction: function(fn)
+    {
+        var fnRegex = /function ([^(]+\([^)]*\)) \{/;
+        var fnText = safeToString(fn);
+
+        var m = fnRegex.exec(fnText);
+        return m ? m[1] : "function()";
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    copySource: function(fn)
+    {
+        copyToClipboard(safeToString(fn));
+    },
+
+    monitor: function(fn, script, monitored)
+    {
+        if (monitored)
+            Firebug.Debugger.unmonitorScript(fn, script, "monitor");
+        else
+            Firebug.Debugger.monitorScript(fn, script, "monitor");
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "function",
+
+    supportsObject: function(object, type)
+    {
+        return isFunction(object);
+    },
+
+    inspectObject: function(fn, context)
+    {
+        var sourceLink = findSourceForFunction(fn, context);
+        if (sourceLink)
+            Firebug.chrome.select(sourceLink);
+        if (FBTrace.DBG_FUNCTION_NAME)
+            FBTrace.sysout("reps.function.inspectObject selected sourceLink is ", sourceLink);
+    },
+
+    getTooltip: function(fn, context)
+    {
+        var script = findScriptForFunctionInContext(context, fn);
+        if (script)
+            return $STRF("Line", [normalizeURL(script.fileName), script.baseLineNumber]);
+        else
+            if (fn.toString)
+                return fn.toString();
+    },
+
+    getTitle: function(fn, context)
+    {
+        var name = fn.name ? fn.name : "function";
+        return name + "()";
+    },
+
+    getContextMenuItems: function(fn, target, context, script)
+    {
+        if (!script)
+            script = findScriptForFunctionInContext(context, fn);
+        if (!script)
+            return;
+
+        var scriptInfo = getSourceFileAndLineByScript(context, script);
+        var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
+
+        var name = script ? getFunctionName(script, context) : fn.name;
+        return [
+            {label: "CopySource", command: bindFixed(this.copySource, this, fn) },
+            "-",
+            {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
+             type: "checkbox", checked: monitored,
+             command: bindFixed(this.monitor, this, fn, script, monitored) }
+        ];
+    }
+});
+
+// ************************************************************************************************
+/*
+this.jsdScript = domplate(Firebug.Rep,
+{
+    copySource: function(script)
+    {
+        var fn = script.functionObject.getWrappedValue();
+        return FirebugReps.Func.copySource(fn);
+    },
+
+    monitor: function(fn, script, monitored)
+    {
+        fn = script.functionObject.getWrappedValue();
+        return FirebugReps.Func.monitor(fn, script, monitored);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "jsdScript",
+    inspectable: false,
+
+    supportsObject: function(object, type)
+    {
+        return object instanceof jsdIScript;
+    },
+
+    inspectObject: function(script, context)
+    {
+        var sourceLink = getSourceLinkForScript(script, context);
+        if (sourceLink)
+            Firebug.chrome.select(sourceLink);
+    },
+
+    getRealObject: function(script, context)
+    {
+        return script;
+    },
+
+    getTooltip: function(script)
+    {
+        return $STRF("jsdIScript", [script.tag]);
+    },
+
+    getTitle: function(script, context)
+    {
+        var fn = script.functionObject.getWrappedValue();
+        return FirebugReps.Func.getTitle(fn, context);
+    },
+
+    getContextMenuItems: function(script, target, context)
+    {
+        var fn = script.functionObject.getWrappedValue();
+
+        var scriptInfo = getSourceFileAndLineByScript(context, script);
+           var monitored = scriptInfo ? fbs.isMonitored(scriptInfo.sourceFile.href, scriptInfo.lineNo) : false;
+
+        var name = getFunctionName(script, context);
+
+        return [
+            {label: "CopySource", command: bindFixed(this.copySource, this, script) },
+            "-",
+            {label: $STRF("ShowCallsInConsole", [name]), nol10n: true,
+             type: "checkbox", checked: monitored,
+             command: bindFixed(this.monitor, this, fn, script, monitored) }
+        ];
+    }
+});
+/**/
+//************************************************************************************************
+
+this.Obj = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK(
+            SPAN({"class": "objectTitle"}, "$object|getTitle "),
+
+            SPAN({"class": "objectProps"},
+                SPAN({"class": "objectLeftBrace", role: "presentation"}, "{"),
+                FOR("prop", "$object|propIterator",
+                    SPAN({"class": "objectPropName", role: "presentation"}, "$prop.name"),
+                    SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"),
+                    TAG("$prop.tag", {object: "$prop.object"}),
+                    SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim")
+                ),
+                SPAN({"class": "objectRightBrace"}, "}")
+            )
+        ),
+
+    propNumberTag:
+        SPAN({"class": "objectProp-number"}, "$object"),
+
+    propStringTag:
+        SPAN({"class": "objectProp-string"}, "&quot;$object&quot;"),
+
+    propObjectTag:
+        SPAN({"class": "objectProp-object"}, "$object"),
+
+    propIterator: function (object)
+    {
+        ///Firebug.ObjectShortIteratorMax;
+        var maxLength = 55; // default max length for long representation
+
+        if (!object)
+            return [];
+
+        var props = [];
+        var length = 0;
+
+        var numProperties = 0;
+        var numPropertiesShown = 0;
+        var maxLengthReached = false;
+
+        var lib = this;
+
+        var propRepsMap =
+        {
+            "boolean": this.propNumberTag,
+            "number": this.propNumberTag,
+            "string": this.propStringTag,
+            "object": this.propObjectTag
+        };
+
+        try
+        {
+            var title = Firebug.Rep.getTitle(object);
+            length += title.length;
+
+            for (var name in object)
+            {
+                var value;
+                try
+                {
+                    value = object[name];
+                }
+                catch (exc)
+                {
+                    continue;
+                }
+
+                var type = typeof(value);
+                if (type == "boolean" ||
+                    type == "number" ||
+                    (type == "string" && value) ||
+                    (type == "object" && value && value.toString))
+                {
+                    var tag = propRepsMap[type];
+
+                    var value = (type == "object") ?
+                        Firebug.getRep(value).getTitle(value) :
+                        value + "";
+
+                    length += name.length + value.length + 4;
+
+                    if (length <= maxLength)
+                    {
+                        props.push({
+                            tag: tag,
+                            name: name,
+                            object: value,
+                            equal: "=",
+                            delim: ", "
+                        });
+
+                        numPropertiesShown++;
+                    }
+                    else
+                        maxLengthReached = true;
+
+                }
+
+                numProperties++;
+
+                if (maxLengthReached && numProperties > numPropertiesShown)
+                    break;
+            }
+
+            if (numProperties > numPropertiesShown)
+            {
+                props.push({
+                    object: "...", //xxxHonza localization
+                    tag: FirebugReps.Caption.tag,
+                    name: "",
+                    equal:"",
+                    delim:""
+                });
+            }
+            else if (props.length > 0)
+            {
+                props[props.length-1].delim = '';
+            }
+        }
+        catch (exc)
+        {
+            // Sometimes we get exceptions when trying to read from certain objects, like
+            // StorageList, but don't let that gum up the works
+            // XXXjjb also History.previous fails because object is a web-page object which does not have
+            // permission to read the history
+        }
+        return props;
+    },
+
+    fb_1_6_propIterator: function (object, max)
+    {
+        max = max || 3;
+        if (!object)
+            return [];
+
+        var props = [];
+        var len = 0, count = 0;
+
+        try
+        {
+            for (var name in object)
+            {
+                var value;
+                try
+                {
+                    value = object[name];
+                }
+                catch (exc)
+                {
+                    continue;
+                }
+
+                var t = typeof(value);
+                if (t == "boolean" || t == "number" || (t == "string" && value)
+                    || (t == "object" && value && value.toString))
+                {
+                    var rep = Firebug.getRep(value);
+                    var tag = rep.shortTag || rep.tag;
+                    if (t == "object")
+                    {
+                        value = rep.getTitle(value);
+                        tag = rep.titleTag;
+                    }
+                    count++;
+                    if (count <= max)
+                        props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "});
+                    else
+                        break;
+                }
+            }
+            if (count > max)
+            {
+                props[Math.max(1,max-1)] = {
+                    object: "more...", //xxxHonza localization
+                    tag: FirebugReps.Caption.tag,
+                    name: "",
+                    equal:"",
+                    delim:""
+                };
+            }
+            else if (props.length > 0)
+            {
+                props[props.length-1].delim = '';
+            }
+        }
+        catch (exc)
+        {
+            // Sometimes we get exceptions when trying to read from certain objects, like
+            // StorageList, but don't let that gum up the works
+            // XXXjjb also History.previous fails because object is a web-page object which does not have
+            // permission to read the history
+        }
+        return props;
+    },
+
+    /*
+    propIterator: function (object)
+    {
+        if (!object)
+            return [];
+
+        var props = [];
+        var len = 0;
+
+        try
+        {
+            for (var name in object)
+            {
+                var val;
+                try
+                {
+                    val = object[name];
+                }
+                catch (exc)
+                {
+                    continue;
+                }
+
+                var t = typeof val;
+                if (t == "boolean" || t == "number" || (t == "string" && val)
+                    || (t == "object" && !isFunction(val) && val && val.toString))
+                {
+                    var title = (t == "object")
+                        ? Firebug.getRep(val).getTitle(val)
+                        : val+"";
+
+                    len += name.length + title.length + 1;
+                    if (len < 50)
+                        props.push({name: name, value: title});
+                    else
+                        break;
+                }
+            }
+        }
+        catch (exc)
+        {
+            // Sometimes we get exceptions when trying to read from certain objects, like
+            // StorageList, but don't let that gum up the works
+            // XXXjjb also History.previous fails because object is a web-page object which does not have
+            // permission to read the history
+        }
+
+        return props;
+    },
+    /**/
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "object",
+
+    supportsObject: function(object, type)
+    {
+        return true;
+    }
+});
+
+
+// ************************************************************************************************
+
+this.Arr = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTBOX({_repObject: "$object"},
+            SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
+            FOR("item", "$object|arrayIterator",
+                TAG("$item.tag", {object: "$item.object"}),
+                SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
+            ),
+            SPAN({"class": "arrayRightBracket", role : "presentation"}, "]")
+        ),
+
+    shortTag:
+        OBJECTBOX({_repObject: "$object"},
+            SPAN({"class": "arrayLeftBracket", role : "presentation"}, "["),
+            FOR("item", "$object|shortArrayIterator",
+                TAG("$item.tag", {object: "$item.object"}),
+                SPAN({"class": "arrayComma", role : "presentation"}, "$item.delim")
+            ),
+            // TODO: xxxpedro - confirm this on Firebug
+            //FOR("prop", "$object|shortPropIterator",
+            //        " $prop.name=",
+            //        SPAN({"class": "objectPropValue"}, "$prop.value|cropString")
+            //),
+            SPAN({"class": "arrayRightBracket"}, "]")
+        ),
+
+    arrayIterator: function(array)
+    {
+        var items = [];
+        for (var i = 0; i < array.length; ++i)
+        {
+            var value = array[i];
+            var rep = Firebug.getRep(value);
+            var tag = rep.shortTag ? rep.shortTag : rep.tag;
+            var delim = (i == array.length-1 ? "" : ", ");
+
+            items.push({object: value, tag: tag, delim: delim});
+        }
+
+        return items;
+    },
+
+    shortArrayIterator: function(array)
+    {
+        var items = [];
+        for (var i = 0; i < array.length && i < 3; ++i)
+        {
+            var value = array[i];
+            var rep = Firebug.getRep(value);
+            var tag = rep.shortTag ? rep.shortTag : rep.tag;
+            var delim = (i == array.length-1 ? "" : ", ");
+
+            items.push({object: value, tag: tag, delim: delim});
+        }
+
+        if (array.length > 3)
+            items.push({object: (array.length-3) + " more...", tag: FirebugReps.Caption.tag, delim: ""});
+
+        return items;
+    },
+
+    shortPropIterator:    this.Obj.propIterator,
+
+    getItemIndex: function(child)
+    {
+        var arrayIndex = 0;
+        for (child = child.previousSibling; child; child = child.previousSibling)
+        {
+            if (child.repObject)
+                ++arrayIndex;
+        }
+        return arrayIndex;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "array",
+
+    supportsObject: function(object)
+    {
+        return this.isArray(object);
+    },
+
+    // http://code.google.com/p/fbug/issues/detail?id=874
+    // BEGIN Yahoo BSD Source (modified here)  YAHOO.lang.isArray, YUI 2.2.2 June 2007
+    isArray: function(obj) {
+        try {
+            if (!obj)
+                return false;
+            else if (isIE && !isFunction(obj) && typeof obj == "object" && isFinite(obj.length) && obj.nodeType != 8)
+                return true;
+            else if (isFinite(obj.length) && isFunction(obj.splice))
+                return true;
+            else if (isFinite(obj.length) && isFunction(obj.callee)) // arguments
+                return true;
+            else if (instanceOf(obj, "HTMLCollection"))
+                return true;
+            else if (instanceOf(obj, "NodeList"))
+                return true;
+            else
+                return false;
+        }
+        catch(exc)
+        {
+            if (FBTrace.DBG_ERRORS)
+            {
+                FBTrace.sysout("isArray FAILS:", exc);  /* Something weird: without the try/catch, OOM, with no exception?? */
+                FBTrace.sysout("isArray Fails on obj", obj);
+            }
+        }
+
+        return false;
+    },
+    // END Yahoo BSD SOURCE See license below.
+
+    getTitle: function(object, context)
+    {
+        return "[" + object.length + "]";
+    }
+});
+
+// ************************************************************************************************
+
+this.Property = domplate(Firebug.Rep,
+{
+    supportsObject: function(object)
+    {
+        return object instanceof Property;
+    },
+
+    getRealObject: function(prop, context)
+    {
+        return prop.object[prop.name];
+    },
+
+    getTitle: function(prop, context)
+    {
+        return prop.name;
+    }
+});
+
+// ************************************************************************************************
+
+this.NetFile = domplate(this.Obj,
+{
+    supportsObject: function(object)
+    {
+        return object instanceof Firebug.NetFile;
+    },
+
+    browseObject: function(file, context)
+    {
+        openNewTab(file.href);
+        return true;
+    },
+
+    getRealObject: function(file, context)
+    {
+        return null;
+    }
+});
+
+// ************************************************************************************************
+
+this.Except = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTBOX({_repObject: "$object"}, "$object.message"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "exception",
+
+    supportsObject: function(object)
+    {
+        return object instanceof ErrorCopy;
+    }
+});
+
+
+// ************************************************************************************************
+
+this.Element = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK(
+            "&lt;",
+            SPAN({"class": "nodeTag"}, "$object.nodeName|toLowerCase"),
+            FOR("attr", "$object|attrIterator",
+                "&nbsp;$attr.nodeName=&quot;", SPAN({"class": "nodeValue"}, "$attr.nodeValue"), "&quot;"
+            ),
+            "&gt;"
+         ),
+
+    shortTag:
+        OBJECTLINK(
+            SPAN({"class": "$object|getVisible"},
+                SPAN({"class": "selectorTag"}, "$object|getSelectorTag"),
+                SPAN({"class": "selectorId"}, "$object|getSelectorId"),
+                SPAN({"class": "selectorClass"}, "$object|getSelectorClass"),
+                SPAN({"class": "selectorValue"}, "$object|getValue")
+            )
+         ),
+
+     getVisible: function(elt)
+     {
+         return isVisible(elt) ? "" : "selectorHidden";
+     },
+
+     getSelectorTag: function(elt)
+     {
+         return elt.nodeName.toLowerCase();
+     },
+
+     getSelectorId: function(elt)
+     {
+         return elt.id ? "#" + elt.id : "";
+     },
+
+     getSelectorClass: function(elt)
+     {
+         return elt.className ? "." + elt.className.split(" ")[0] : "";
+     },
+
+     getValue: function(elt)
+     {
+         // TODO: xxxpedro
+         return "";
+         var value;
+         if (elt instanceof HTMLImageElement)
+             value = getFileName(elt.src);
+         else if (elt instanceof HTMLAnchorElement)
+             value = getFileName(elt.href);
+         else if (elt instanceof HTMLInputElement)
+             value = elt.value;
+         else if (elt instanceof HTMLFormElement)
+             value = getFileName(elt.action);
+         else if (elt instanceof HTMLScriptElement)
+             value = getFileName(elt.src);
+
+         return value ? " " + cropString(value, 20) : "";
+     },
+
+     attrIterator: function(elt)
+     {
+         var attrs = [];
+         var idAttr, classAttr;
+         if (elt.attributes)
+         {
+             for (var i = 0; i < elt.attributes.length; ++i)
+             {
+                 var attr = elt.attributes[i];
+
+                 // we must check if the attribute is specified otherwise IE will show them
+                 if (!attr.specified || attr.nodeName && attr.nodeName.indexOf("firebug-") != -1)
+                    continue;
+                 else if (attr.nodeName == "id")
+                    idAttr = attr;
+                 else if (attr.nodeName == "class")
+                    classAttr = attr;
+                 else if (attr.nodeName == "style")
+                    attrs.push({
+                        nodeName: attr.nodeName,
+                        nodeValue: attr.nodeValue ||
+                        // IE won't recognize the attr.nodeValue of <style> nodes ...
+                        // and will return CSS property names in upper case, so we need to convert them
+                        elt.style.cssText.replace(/([^\s]+)\s*:/g,
+                                function(m,g){return g.toLowerCase()+":"})
+                    });
+                 else
+                    attrs.push(attr);
+             }
+         }
+         if (classAttr)
+            attrs.splice(0, 0, classAttr);
+         if (idAttr)
+            attrs.splice(0, 0, idAttr);
+
+         return attrs;
+     },
+
+     shortAttrIterator: function(elt)
+     {
+         var attrs = [];
+         if (elt.attributes)
+         {
+             for (var i = 0; i < elt.attributes.length; ++i)
+             {
+                 var attr = elt.attributes[i];
+                 if (attr.nodeName == "id" || attr.nodeName == "class")
+                     attrs.push(attr);
+             }
+         }
+
+         return attrs;
+     },
+
+     getHidden: function(elt)
+     {
+         return isVisible(elt) ? "" : "nodeHidden";
+     },
+
+     getXPath: function(elt)
+     {
+         return getElementTreeXPath(elt);
+     },
+
+     // TODO: xxxpedro remove this?
+     getNodeText: function(element)
+     {
+         var text = element.textContent;
+         if (Firebug.showFullTextNodes)
+            return text;
+        else
+            return cropString(text, 50);
+     },
+     /**/
+
+     getNodeTextGroups: function(element)
+     {
+         var text =  element.textContent;
+         if (!Firebug.showFullTextNodes)
+         {
+             text=cropString(text,50);
+         }
+
+         var escapeGroups=[];
+
+         if (Firebug.showTextNodesWithWhitespace)
+             escapeGroups.push({
+                'group': 'whitespace',
+                'class': 'nodeWhiteSpace',
+                'extra': {
+                    '\t': '_Tab',
+                    '\n': '_Para',
+                    ' ' : '_Space'
+                }
+             });
+         if (Firebug.showTextNodesWithEntities)
+             escapeGroups.push({
+                 'group':'text',
+                 'class':'nodeTextEntity',
+                 'extra':{}
+             });
+
+         if (escapeGroups.length)
+             return escapeGroupsForEntities(text, escapeGroups);
+         else
+             return [{str:text,'class':'',extra:''}];
+     },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    copyHTML: function(elt)
+    {
+        var html = getElementXML(elt);
+        copyToClipboard(html);
+    },
+
+    copyInnerHTML: function(elt)
+    {
+        copyToClipboard(elt.innerHTML);
+    },
+
+    copyXPath: function(elt)
+    {
+        var xpath = getElementXPath(elt);
+        copyToClipboard(xpath);
+    },
+
+    persistor: function(context, xpath)
+    {
+        var elts = xpath
+            ? getElementsByXPath(context.window.document, xpath)
+            : null;
+
+        return elts && elts.length ? elts[0] : null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "element",
+
+    supportsObject: function(object)
+    {
+        //return object instanceof Element || object.nodeType == 1 && typeof object.nodeName == "string";
+        return instanceOf(object, "Element");
+    },
+
+    browseObject: function(elt, context)
+    {
+        var tag = elt.nodeName.toLowerCase();
+        if (tag == "script")
+            openNewTab(elt.src);
+        else if (tag == "link")
+            openNewTab(elt.href);
+        else if (tag == "a")
+            openNewTab(elt.href);
+        else if (tag == "img")
+            openNewTab(elt.src);
+
+        return true;
+    },
+
+    persistObject: function(elt, context)
+    {
+        var xpath = getElementXPath(elt);
+
+        return bind(this.persistor, top, xpath);
+    },
+
+    getTitle: function(element, context)
+    {
+        return getElementCSSSelector(element);
+    },
+
+    getTooltip: function(elt)
+    {
+        return this.getXPath(elt);
+    },
+
+    getContextMenuItems: function(elt, target, context)
+    {
+        var monitored = areEventsMonitored(elt, null, context);
+
+        return [
+            {label: "CopyHTML", command: bindFixed(this.copyHTML, this, elt) },
+            {label: "CopyInnerHTML", command: bindFixed(this.copyInnerHTML, this, elt) },
+            {label: "CopyXPath", command: bindFixed(this.copyXPath, this, elt) },
+            "-",
+            {label: "ShowEventsInConsole", type: "checkbox", checked: monitored,
+             command: bindFixed(toggleMonitorEvents, FBL, elt, null, monitored, context) },
+            "-",
+            {label: "ScrollIntoView", command: bindFixed(elt.scrollIntoView, elt) }
+        ];
+    }
+});
+
+// ************************************************************************************************
+
+this.TextNode = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK(
+            "&lt;",
+            SPAN({"class": "nodeTag"}, "TextNode"),
+            "&nbsp;textContent=&quot;", SPAN({"class": "nodeValue"}, "$object.textContent|cropString"), "&quot;",
+            "&gt;"
+            ),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "textNode",
+
+    supportsObject: function(object)
+    {
+        return object instanceof Text;
+    }
+});
+
+// ************************************************************************************************
+
+this.Document = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK("Document ", SPAN({"class": "objectPropValue"}, "$object|getLocation")),
+
+    getLocation: function(doc)
+    {
+        return doc.location ? getFileName(doc.location.href) : "";
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "object",
+
+    supportsObject: function(object)
+    {
+        //return object instanceof Document || object instanceof XMLDocument;
+        return instanceOf(object, "Document");
+    },
+
+    browseObject: function(doc, context)
+    {
+        openNewTab(doc.location.href);
+        return true;
+    },
+
+    persistObject: function(doc, context)
+    {
+        return this.persistor;
+    },
+
+    persistor: function(context)
+    {
+        return context.window.document;
+    },
+
+    getTitle: function(win, context)
+    {
+        return "document";
+    },
+
+    getTooltip: function(doc)
+    {
+        return doc.location.href;
+    }
+});
+
+// ************************************************************************************************
+
+this.StyleSheet = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK("StyleSheet ", SPAN({"class": "objectPropValue"}, "$object|getLocation")),
+
+    getLocation: function(styleSheet)
+    {
+        return getFileName(styleSheet.href);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    copyURL: function(styleSheet)
+    {
+        copyToClipboard(styleSheet.href);
+    },
+
+    openInTab: function(styleSheet)
+    {
+        openNewTab(styleSheet.href);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "object",
+
+    supportsObject: function(object)
+    {
+        //return object instanceof CSSStyleSheet;
+        return instanceOf(object, "CSSStyleSheet");
+    },
+
+    browseObject: function(styleSheet, context)
+    {
+        openNewTab(styleSheet.href);
+        return true;
+    },
+
+    persistObject: function(styleSheet, context)
+    {
+        return bind(this.persistor, top, styleSheet.href);
+    },
+
+    getTooltip: function(styleSheet)
+    {
+        return styleSheet.href;
+    },
+
+    getContextMenuItems: function(styleSheet, target, context)
+    {
+        return [
+            {label: "CopyLocation", command: bindFixed(this.copyURL, this, styleSheet) },
+            "-",
+            {label: "OpenInTab", command: bindFixed(this.openInTab, this, styleSheet) }
+        ];
+    },
+
+    persistor: function(context, href)
+    {
+        return getStyleSheetByHref(href, context);
+    }
+});
+
+// ************************************************************************************************
+
+this.Window = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK("Window ", SPAN({"class": "objectPropValue"}, "$object|getLocation")),
+
+    getLocation: function(win)
+    {
+        try
+        {
+            return (win && win.location && !win.closed) ? getFileName(win.location.href) : "";
+        }
+        catch (exc)
+        {
+            if (FBTrace.DBG_ERRORS)
+                FBTrace.sysout("reps.Window window closed?");
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "object",
+
+    supportsObject: function(object)
+    {
+        return instanceOf(object, "Window");
+    },
+
+    browseObject: function(win, context)
+    {
+        openNewTab(win.location.href);
+        return true;
+    },
+
+    persistObject: function(win, context)
+    {
+        return this.persistor;
+    },
+
+    persistor: function(context)
+    {
+        return context.window;
+    },
+
+    getTitle: function(win, context)
+    {
+        return "window";
+    },
+
+    getTooltip: function(win)
+    {
+        if (win && !win.closed)
+            return win.location.href;
+    }
+});
+
+// ************************************************************************************************
+
+this.Event = domplate(Firebug.Rep,
+{
+    tag: TAG("$copyEventTag", {object: "$object|copyEvent"}),
+
+    copyEventTag:
+        OBJECTLINK("$object|summarizeEvent"),
+
+    summarizeEvent: function(event)
+    {
+        var info = [event.type, ' '];
+
+        var eventFamily = getEventFamily(event.type);
+        if (eventFamily == "mouse")
+            info.push("clientX=", event.clientX, ", clientY=", event.clientY);
+        else if (eventFamily == "key")
+            info.push("charCode=", event.charCode, ", keyCode=", event.keyCode);
+
+        return info.join("");
+    },
+
+    copyEvent: function(event)
+    {
+        return new EventCopy(event);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "object",
+
+    supportsObject: function(object)
+    {
+        //return object instanceof Event || object instanceof EventCopy;
+        return instanceOf(object, "Event") || instanceOf(object, "EventCopy");
+    },
+
+    getTitle: function(event, context)
+    {
+        return "Event " + event.type;
+    }
+});
+
+// ************************************************************************************************
+
+this.SourceLink = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"),
+
+    hideSourceLink: function(sourceLink)
+    {
+        return sourceLink ? sourceLink.href.indexOf("XPCSafeJSObjectWrapper") != -1 : true;
+    },
+
+    getSourceLinkTitle: function(sourceLink)
+    {
+        if (!sourceLink)
+            return "";
+
+        try
+        {
+            var fileName = getFileName(sourceLink.href);
+            fileName = decodeURIComponent(fileName);
+            fileName = cropString(fileName, 17);
+        }
+        catch(exc)
+        {
+            if (FBTrace.DBG_ERRORS)
+                FBTrace.sysout("reps.getSourceLinkTitle decodeURIComponent fails for \'"+fileName+"\': "+exc, exc);
+        }
+
+        return typeof sourceLink.line == "number" ?
+                fileName + " (line " + sourceLink.line + ")" :
+                fileName;
+
+        // TODO: xxxpedro
+        //return $STRF("Line", [fileName, sourceLink.line]);
+    },
+
+    copyLink: function(sourceLink)
+    {
+        copyToClipboard(sourceLink.href);
+    },
+
+    openInTab: function(sourceLink)
+    {
+        openNewTab(sourceLink.href);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "sourceLink",
+
+    supportsObject: function(object)
+    {
+        return object instanceof SourceLink;
+    },
+
+    getTooltip: function(sourceLink)
+    {
+        return decodeURI(sourceLink.href);
+    },
+
+    inspectObject: function(sourceLink, context)
+    {
+        if (sourceLink.type == "js")
+        {
+            var scriptFile = getSourceFileByHref(sourceLink.href, context);
+            if (scriptFile)
+                return Firebug.chrome.select(sourceLink);
+        }
+        else if (sourceLink.type == "css")
+        {
+            // If an object is defined, treat it as the highest priority for
+            // inspect actions
+            if (sourceLink.object) {
+                Firebug.chrome.select(sourceLink.object);
+                return;
+            }
+
+            var stylesheet = getStyleSheetByHref(sourceLink.href, context);
+            if (stylesheet)
+            {
+                var ownerNode = stylesheet.ownerNode;
+                if (ownerNode)
+                {
+                    Firebug.chrome.select(sourceLink, "html");
+                    return;
+                }
+
+                var panel = context.getPanel("stylesheet");
+                if (panel && panel.getRuleByLine(stylesheet, sourceLink.line))
+                    return Firebug.chrome.select(sourceLink);
+            }
+        }
+
+        // Fallback is to just open the view-source window on the file
+        viewSource(sourceLink.href, sourceLink.line);
+    },
+
+    browseObject: function(sourceLink, context)
+    {
+        openNewTab(sourceLink.href);
+        return true;
+    },
+
+    getContextMenuItems: function(sourceLink, target, context)
+    {
+        return [
+            {label: "CopyLocation", command: bindFixed(this.copyLink, this, sourceLink) },
+            "-",
+            {label: "OpenInTab", command: bindFixed(this.openInTab, this, sourceLink) }
+        ];
+    }
+});
+
+// ************************************************************************************************
+
+this.SourceFile = domplate(this.SourceLink,
+{
+    tag:
+        OBJECTLINK({$collapsed: "$object|hideSourceLink"}, "$object|getSourceLinkTitle"),
+
+    persistor: function(context, href)
+    {
+        return getSourceFileByHref(href, context);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "sourceFile",
+
+    supportsObject: function(object)
+    {
+        return object instanceof SourceFile;
+    },
+
+    persistObject: function(sourceFile)
+    {
+        return bind(this.persistor, top, sourceFile.href);
+    },
+
+    browseObject: function(sourceLink, context)
+    {
+    },
+
+    getTooltip: function(sourceFile)
+    {
+        return sourceFile.href;
+    }
+});
+
+// ************************************************************************************************
+
+this.StackFrame = domplate(Firebug.Rep,  // XXXjjb Since the repObject is fn the stack does not have correct line numbers
+{
+    tag:
+        OBJECTBLOCK(
+            A({"class": "objectLink objectLink-function focusRow a11yFocus", _repObject: "$object.fn"}, "$object|getCallName"),
+            " ( ",
+            FOR("arg", "$object|argIterator",
+                TAG("$arg.tag", {object: "$arg.value"}),
+                SPAN({"class": "arrayComma"}, "$arg.delim")
+            ),
+            " )",
+            SPAN({"class": "objectLink-sourceLink objectLink"}, "$object|getSourceLinkTitle")
+        ),
+
+    getCallName: function(frame)
+    {
+        //TODO: xxxpedro reps StackFrame
+        return frame.name || "anonymous";
+
+        //return getFunctionName(frame.script, frame.context);
+    },
+
+    getSourceLinkTitle: function(frame)
+    {
+        //TODO: xxxpedro reps StackFrame
+        var fileName = cropString(getFileName(frame.href), 20);
+        return fileName + (frame.lineNo ? " (line " + frame.lineNo + ")" : "");
+
+        var fileName = cropString(getFileName(frame.href), 17);
+        return $STRF("Line", [fileName, frame.lineNo]);
+    },
+
+    argIterator: function(frame)
+    {
+        if (!frame.args)
+            return [];
+
+        var items = [];
+
+        for (var i = 0; i < frame.args.length; ++i)
+        {
+            var arg = frame.args[i];
+
+            if (!arg)
+                break;
+
+            var rep = Firebug.getRep(arg.value);
+            var tag = rep.shortTag ? rep.shortTag : rep.tag;
+
+            var delim = (i == frame.args.length-1 ? "" : ", ");
+
+            items.push({name: arg.name, value: arg.value, tag: tag, delim: delim});
+        }
+
+        return items;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "stackFrame",
+
+    supportsObject: function(object)
+    {
+        return object instanceof StackFrame;
+    },
+
+    inspectObject: function(stackFrame, context)
+    {
+        var sourceLink = new SourceLink(stackFrame.href, stackFrame.lineNo, "js");
+        Firebug.chrome.select(sourceLink);
+    },
+
+    getTooltip: function(stackFrame, context)
+    {
+        return $STRF("Line", [stackFrame.href, stackFrame.lineNo]);
+    }
+
+});
+
+// ************************************************************************************************
+
+this.StackTrace = domplate(Firebug.Rep,
+{
+    tag:
+        FOR("frame", "$object.frames focusRow",
+            TAG(this.StackFrame.tag, {object: "$frame"})
+        ),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "stackTrace",
+
+    supportsObject: function(object)
+    {
+        return object instanceof StackTrace;
+    }
+});
+
+// ************************************************************************************************
+
+this.jsdStackFrame = domplate(Firebug.Rep,
+{
+    inspectable: false,
+
+    supportsObject: function(object)
+    {
+        return (object instanceof jsdIStackFrame) && (object.isValid);
+    },
+
+    getTitle: function(frame, context)
+    {
+        if (!frame.isValid) return "(invalid frame)"; // XXXjjb avoid frame.script == null
+        return getFunctionName(frame.script, context);
+    },
+
+    getTooltip: function(frame, context)
+    {
+        if (!frame.isValid) return "(invalid frame)";  // XXXjjb avoid frame.script == null
+        var sourceInfo = FBL.getSourceFileAndLineByScript(context, frame.script, frame);
+        if (sourceInfo)
+            return $STRF("Line", [sourceInfo.sourceFile.href, sourceInfo.lineNo]);
+        else
+            return $STRF("Line", [frame.script.fileName, frame.line]);
+    },
+
+    getContextMenuItems: function(frame, target, context)
+    {
+        var fn = frame.script.functionObject.getWrappedValue();
+        return FirebugReps.Func.getContextMenuItems(fn, target, context, frame.script);
+    }
+});
+
+// ************************************************************************************************
+
+this.ErrorMessage = domplate(Firebug.Rep,
+{
+    tag:
+        OBJECTBOX({
+                $hasTwisty: "$object|hasStackTrace",
+                $hasBreakSwitch: "$object|hasBreakSwitch",
+                $breakForError: "$object|hasErrorBreak",
+                _repObject: "$object",
+                _stackTrace: "$object|getLastErrorStackTrace",
+                onclick: "$onToggleError"},
+
+            DIV({"class": "errorTitle a11yFocus", role : 'checkbox', 'aria-checked' : 'false'},
+                "$object.message|getMessage"
+            ),
+            DIV({"class": "errorTrace"}),
+            DIV({"class": "errorSourceBox errorSource-$object|getSourceType"},
+                IMG({"class": "errorBreak a11yFocus", src:"blank.gif", role : 'checkbox', 'aria-checked':'false', title: "Break on this error"}),
+                A({"class": "errorSource a11yFocus"}, "$object|getLine")
+            ),
+            TAG(this.SourceLink.tag, {object: "$object|getSourceLink"})
+        ),
+
+    getLastErrorStackTrace: function(error)
+    {
+        return error.trace;
+    },
+
+    hasStackTrace: function(error)
+    {
+        var url = error.href.toString();
+        var fromCommandLine = (url.indexOf("XPCSafeJSObjectWrapper") != -1);
+        return !fromCommandLine && error.trace;
+    },
+
+    hasBreakSwitch: function(error)
+    {
+        return error.href && error.lineNo > 0;
+    },
+
+    hasErrorBreak: function(error)
+    {
+        return fbs.hasErrorBreakpoint(error.href, error.lineNo);
+    },
+
+    getMessage: function(message)
+    {
+        var re = /\[Exception... "(.*?)" nsresult:/;
+        var m = re.exec(message);
+        return m ? m[1] : message;
+    },
+
+    getLine: function(error)
+    {
+        if (error.category == "js")
+        {
+            if (error.source)
+                return cropString(error.source, 80);
+            else if (error.href && error.href.indexOf("XPCSafeJSObjectWrapper") == -1)
+                return cropString(error.getSourceLine(), 80);
+        }
+    },
+
+    getSourceLink: function(error)
+    {
+        var ext = error.category == "css" ? "css" : "js";
+        return error.lineNo ? new SourceLink(error.href, error.lineNo, ext) : null;
+    },
+
+    getSourceType: function(error)
+    {
+        // Errors occurring inside of HTML event handlers look like "foo.html (line 1)"
+        // so let's try to skip those
+        if (error.source)
+            return "syntax";
+        else if (error.lineNo == 1 && getFileExtension(error.href) != "js")
+            return "none";
+        else if (error.category == "css")
+            return "none";
+        else if (!error.href || !error.lineNo)
+            return "none";
+        else
+            return "exec";
+    },
+
+    onToggleError: function(event)
+    {
+        var target = event.currentTarget;
+        if (hasClass(event.target, "errorBreak"))
+        {
+            this.breakOnThisError(target.repObject);
+        }
+        else if (hasClass(event.target, "errorSource"))
+        {
+            var panel = Firebug.getElementPanel(event.target);
+            this.inspectObject(target.repObject, panel.context);
+        }
+        else if (hasClass(event.target, "errorTitle"))
+        {
+            var traceBox = target.childNodes[1];
+            toggleClass(target, "opened");
+            event.target.setAttribute('aria-checked', hasClass(target, "opened"));
+            if (hasClass(target, "opened"))
+            {
+                if (target.stackTrace)
+                    var node = FirebugReps.StackTrace.tag.append({object: target.stackTrace}, traceBox);
+                if (Firebug.A11yModel.enabled)
+                {
+                    var panel = Firebug.getElementPanel(event.target);
+                    dispatch([Firebug.A11yModel], "onLogRowContentCreated", [panel , traceBox]);
+                }
+            }
+            else
+                clearNode(traceBox);
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    copyError: function(error)
+    {
+        var message = [
+            this.getMessage(error.message),
+            error.href,
+            "Line " +  error.lineNo
+        ];
+        copyToClipboard(message.join("\n"));
+    },
+
+    breakOnThisError: function(error)
+    {
+        if (this.hasErrorBreak(error))
+            Firebug.Debugger.clearErrorBreakpoint(error.href, error.lineNo);
+        else
+            Firebug.Debugger.setErrorBreakpoint(error.href, error.lineNo);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "errorMessage",
+    inspectable: false,
+
+    supportsObject: function(object)
+    {
+        return object instanceof ErrorMessage;
+    },
+
+    inspectObject: function(error, context)
+    {
+        var sourceLink = this.getSourceLink(error);
+        FirebugReps.SourceLink.inspectObject(sourceLink, context);
+    },
+
+    getContextMenuItems: function(error, target, context)
+    {
+        var breakOnThisError = this.hasErrorBreak(error);
+
+        var items = [
+            {label: "CopyError", command: bindFixed(this.copyError, this, error) }
+        ];
+
+        if (error.category == "css")
+        {
+            items.push(
+                "-",
+                {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError,
+                 command: bindFixed(this.breakOnThisError, this, error) },
+
+                optionMenu("BreakOnAllErrors", "breakOnErrors")
+            );
+        }
+
+        return items;
+    }
+});
+
+// ************************************************************************************************
+
+this.Assert = domplate(Firebug.Rep,
+{
+    tag:
+        DIV(
+            DIV({"class": "errorTitle"}),
+            DIV({"class": "assertDescription"})
+        ),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "assert",
+
+    inspectObject: function(error, context)
+    {
+        var sourceLink = this.getSourceLink(error);
+        Firebug.chrome.select(sourceLink);
+    },
+
+    getContextMenuItems: function(error, target, context)
+    {
+        var breakOnThisError = this.hasErrorBreak(error);
+
+        return [
+            {label: "CopyError", command: bindFixed(this.copyError, this, error) },
+            "-",
+            {label: "BreakOnThisError", type: "checkbox", checked: breakOnThisError,
+             command: bindFixed(this.breakOnThisError, this, error) },
+            {label: "BreakOnAllErrors", type: "checkbox", checked: Firebug.breakOnErrors,
+             command: bindFixed(this.breakOnAllErrors, this, error) }
+        ];
+    }
+});
+
+// ************************************************************************************************
+
+this.SourceText = domplate(Firebug.Rep,
+{
+    tag:
+        DIV(
+            FOR("line", "$object|lineIterator",
+                DIV({"class": "sourceRow", role : "presentation"},
+                    SPAN({"class": "sourceLine", role : "presentation"}, "$line.lineNo"),
+                    SPAN({"class": "sourceRowText", role : "presentation"}, "$line.text")
+                )
+            )
+        ),
+
+    lineIterator: function(sourceText)
+    {
+        var maxLineNoChars = (sourceText.lines.length + "").length;
+        var list = [];
+
+        for (var i = 0; i < sourceText.lines.length; ++i)
+        {
+            // Make sure all line numbers are the same width (with a fixed-width font)
+            var lineNo = (i+1) + "";
+            while (lineNo.length < maxLineNoChars)
+                lineNo = " " + lineNo;
+
+            list.push({lineNo: lineNo, text: sourceText.lines[i]});
+        }
+
+        return list;
+    },
+
+    getHTML: function(sourceText)
+    {
+        return getSourceLineRange(sourceText, 1, sourceText.lines.length);
+    }
+});
+
+//************************************************************************************************
+this.nsIDOMHistory = domplate(Firebug.Rep,
+{
+    tag:OBJECTBOX({onclick: "$showHistory"},
+            OBJECTLINK("$object|summarizeHistory")
+        ),
+
+    className: "nsIDOMHistory",
+
+    summarizeHistory: function(history)
+    {
+        try
+        {
+            var items = history.length;
+            return items + " history entries";
+        }
+        catch(exc)
+        {
+            return "object does not support history (nsIDOMHistory)";
+        }
+    },
+
+    showHistory: function(history)
+    {
+        try
+        {
+            var items = history.length;  // if this throws, then unsupported
+            Firebug.chrome.select(history);
+        }
+        catch (exc)
+        {
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    supportsObject: function(object, type)
+    {
+        return (object instanceof Ci.nsIDOMHistory);
+    }
+});
+
+// ************************************************************************************************
+this.ApplicationCache = domplate(Firebug.Rep,
+{
+    tag:OBJECTBOX({onclick: "$showApplicationCache"},
+            OBJECTLINK("$object|summarizeCache")
+        ),
+
+    summarizeCache: function(applicationCache)
+    {
+        try
+        {
+            return applicationCache.length + " items in offline cache";
+        }
+        catch(exc)
+        {
+            return "https://bugzilla.mozilla.org/show_bug.cgi?id=422264";
+        }
+    },
+
+    showApplicationCache: function(event)
+    {
+        openNewTab("https://bugzilla.mozilla.org/show_bug.cgi?id=422264");
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "applicationCache",
+
+    supportsObject: function(object, type)
+    {
+        if (Ci.nsIDOMOfflineResourceList)
+            return (object instanceof Ci.nsIDOMOfflineResourceList);
+    }
+
+});
+
+this.Storage = domplate(Firebug.Rep,
+{
+    tag: OBJECTBOX({onclick: "$show"}, OBJECTLINK("$object|summarize")),
+
+    summarize: function(storage)
+    {
+        return storage.length +" items in Storage";
+    },
+    show: function(storage)
+    {
+        openNewTab("http://dev.w3.org/html5/webstorage/#storage-0");
+    },
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    className: "Storage",
+
+    supportsObject: function(object, type)
+    {
+        return (object instanceof Storage);
+    }
+
+});
+
+// ************************************************************************************************
+Firebug.registerRep(
+    //this.nsIDOMHistory, // make this early to avoid exceptions
+    this.Undefined,
+    this.Null,
+    this.Number,
+    this.String,
+    this.Window,
+    //this.ApplicationCache, // must come before Arr (array) else exceptions.
+    //this.ErrorMessage,
+    this.Element,
+    //this.TextNode,
+    this.Document,
+    this.StyleSheet,
+    this.Event,
+    //this.SourceLink,
+    //this.SourceFile,
+    //this.StackTrace,
+    //this.StackFrame,
+    //this.jsdStackFrame,
+    //this.jsdScript,
+    //this.NetFile,
+    this.Property,
+    this.Except,
+    this.Arr
+);
+
+Firebug.setDefaultReps(this.Func, this.Obj);
+
+}});
+
+// ************************************************************************************************
+/*
+ * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled "Yahoo BSD Source"
+ * in only this file reps.js.  John J. Barton June 2007.
+ *
+Software License Agreement (BSD License)
+
+Copyright (c) 2006, Yahoo! Inc.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of Yahoo! Inc. nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * /
+ */
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// Constants
+
+var saveTimeout = 400;
+var pageAmount = 10;
+
+// ************************************************************************************************
+// Globals
+
+var currentTarget = null;
+var currentGroup = null;
+var currentPanel = null;
+var currentEditor = null;
+
+var defaultEditor = null;
+
+var originalClassName = null;
+
+var originalValue = null;
+var defaultValue = null;
+var previousValue = null;
+
+var invalidEditor = false;
+var ignoreNextInput = false;
+
+// ************************************************************************************************
+
+Firebug.Editor = extend(Firebug.Module,
+{
+    supportsStopEvent: true,
+
+    dispatchName: "editor",
+    tabCharacter: "    ",
+
+    startEditing: function(target, value, editor)
+    {
+        this.stopEditing();
+
+        if (hasClass(target, "insertBefore") || hasClass(target, "insertAfter"))
+            return;
+
+        var panel = Firebug.getElementPanel(target);
+        if (!panel.editable)
+            return;
+
+        if (FBTrace.DBG_EDITOR)
+            FBTrace.sysout("editor.startEditing " + value, target);
+
+        defaultValue = target.getAttribute("defaultValue");
+        if (value == undefined)
+        {
+            var textContent = isIE ? "innerText" : "textContent";
+            value = target[textContent];
+            if (value == defaultValue)
+                value = "";
+        }
+
+        originalValue = previousValue = value;
+
+        invalidEditor = false;
+        currentTarget = target;
+        currentPanel = panel;
+        currentGroup = getAncestorByClass(target, "editGroup");
+
+        currentPanel.editing = true;
+
+        var panelEditor = currentPanel.getEditor(target, value);
+        currentEditor = editor ? editor : panelEditor;
+        if (!currentEditor)
+            currentEditor = getDefaultEditor(currentPanel);
+
+        var inlineParent = getInlineParent(target);
+        var targetSize = getOffsetSize(inlineParent);
+
+        setClass(panel.panelNode, "editing");
+        setClass(target, "editing");
+        if (currentGroup)
+            setClass(currentGroup, "editing");
+
+        currentEditor.show(target, currentPanel, value, targetSize);
+        //dispatch(this.fbListeners, "onBeginEditing", [currentPanel, currentEditor, target, value]);
+        currentEditor.beginEditing(target, value);
+        if (FBTrace.DBG_EDITOR)
+            FBTrace.sysout("Editor start panel "+currentPanel.name);
+        this.attachListeners(currentEditor, panel.context);
+    },
+
+    stopEditing: function(cancel)
+    {
+        if (!currentTarget)
+            return;
+
+        if (FBTrace.DBG_EDITOR)
+            FBTrace.sysout("editor.stopEditing cancel:" + cancel+" saveTimeout: "+this.saveTimeout);
+
+        clearTimeout(this.saveTimeout);
+        delete this.saveTimeout;
+
+        this.detachListeners(currentEditor, currentPanel.context);
+
+        removeClass(currentPanel.panelNode, "editing");
+        removeClass(currentTarget, "editing");
+        if (currentGroup)
+            removeClass(currentGroup, "editing");
+
+        var value = currentEditor.getValue();
+        if (value == defaultValue)
+            value = "";
+
+        var removeGroup = currentEditor.endEditing(currentTarget, value, cancel);
+
+        try
+        {
+            if (cancel)
+            {
+                //dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, removeGroup && !originalValue]);
+                if (value != originalValue)
+                    this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue);
+
+                if (removeGroup && !originalValue && currentGroup)
+                    currentGroup.parentNode.removeChild(currentGroup);
+            }
+            else if (!value)
+            {
+                this.saveEditAndNotifyListeners(currentTarget, null, previousValue);
+
+                if (removeGroup && currentGroup)
+                    currentGroup.parentNode.removeChild(currentGroup);
+            }
+            else
+                this.save(value);
+        }
+        catch (exc)
+        {
+            //throw exc.message;
+            //ERROR(exc);
+        }
+
+        currentEditor.hide();
+        currentPanel.editing = false;
+
+        //dispatch(this.fbListeners, "onStopEdit", [currentPanel, currentEditor, currentTarget]);
+        //if (FBTrace.DBG_EDITOR)
+        //    FBTrace.sysout("Editor stop panel "+currentPanel.name);
+
+        currentTarget = null;
+        currentGroup = null;
+        currentPanel = null;
+        currentEditor = null;
+        originalValue = null;
+        invalidEditor = false;
+
+        return value;
+    },
+
+    cancelEditing: function()
+    {
+        return this.stopEditing(true);
+    },
+
+    update: function(saveNow)
+    {
+        if (this.saveTimeout)
+            clearTimeout(this.saveTimeout);
+
+        invalidEditor = true;
+
+        currentEditor.layout();
+
+        if (saveNow)
+            this.save();
+        else
+        {
+            var context = currentPanel.context;
+            this.saveTimeout = context.setTimeout(bindFixed(this.save, this), saveTimeout);
+            if (FBTrace.DBG_EDITOR)
+                FBTrace.sysout("editor.update saveTimeout: "+this.saveTimeout);
+        }
+    },
+
+    save: function(value)
+    {
+        if (!invalidEditor)
+            return;
+
+        if (value == undefined)
+            value = currentEditor.getValue();
+        if (FBTrace.DBG_EDITOR)
+            FBTrace.sysout("editor.save saveTimeout: "+this.saveTimeout+" currentPanel: "+(currentPanel?currentPanel.name:"null"));
+        try
+        {
+            this.saveEditAndNotifyListeners(currentTarget, value, previousValue);
+
+            previousValue = value;
+            invalidEditor = false;
+        }
+        catch (exc)
+        {
+            if (FBTrace.DBG_ERRORS)
+                FBTrace.sysout("editor.save FAILS "+exc, exc);
+        }
+    },
+
+    saveEditAndNotifyListeners: function(currentTarget, value, previousValue)
+    {
+        currentEditor.saveEdit(currentTarget, value, previousValue);
+        //dispatch(this.fbListeners, "onSaveEdit", [currentPanel, currentEditor, currentTarget, value, previousValue]);
+    },
+
+    setEditTarget: function(element)
+    {
+        if (!element)
+        {
+            dispatch([Firebug.A11yModel], 'onInlineEditorClose', [currentPanel, currentTarget, true]);
+            this.stopEditing();
+        }
+        else if (hasClass(element, "insertBefore"))
+            this.insertRow(element, "before");
+        else if (hasClass(element, "insertAfter"))
+            this.insertRow(element, "after");
+        else
+            this.startEditing(element);
+    },
+
+    tabNextEditor: function()
+    {
+        if (!currentTarget)
+            return;
+
+        var value = currentEditor.getValue();
+        var nextEditable = currentTarget;
+        do
+        {
+            nextEditable = !value && currentGroup
+                ? getNextOutsider(nextEditable, currentGroup)
+                : getNextByClass(nextEditable, "editable");
+        }
+        while (nextEditable && !nextEditable.offsetHeight);
+
+        this.setEditTarget(nextEditable);
+    },
+
+    tabPreviousEditor: function()
+    {
+        if (!currentTarget)
+            return;
+
+        var value = currentEditor.getValue();
+        var prevEditable = currentTarget;
+        do
+        {
+            prevEditable = !value && currentGroup
+                ? getPreviousOutsider(prevEditable, currentGroup)
+                : getPreviousByClass(prevEditable, "editable");
+        }
+        while (prevEditable && !prevEditable.offsetHeight);
+
+        this.setEditTarget(prevEditable);
+    },
+
+    insertRow: function(relative, insertWhere)
+    {
+        var group =
+            relative || getAncestorByClass(currentTarget, "editGroup") || currentTarget;
+        var value = this.stopEditing();
+
+        currentPanel = Firebug.getElementPanel(group);
+
+        currentEditor = currentPanel.getEditor(group, value);
+        if (!currentEditor)
+            currentEditor = getDefaultEditor(currentPanel);
+
+        currentGroup = currentEditor.insertNewRow(group, insertWhere);
+        if (!currentGroup)
+            return;
+
+        var editable = hasClass(currentGroup, "editable")
+            ? currentGroup
+            : getNextByClass(currentGroup, "editable");
+
+        if (editable)
+            this.setEditTarget(editable);
+    },
+
+    insertRowForObject: function(relative)
+    {
+        var container = getAncestorByClass(relative, "insertInto");
+        if (container)
+        {
+            relative = getChildByClass(container, "insertBefore");
+            if (relative)
+                this.insertRow(relative, "before");
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    attachListeners: function(editor, context)
+    {
+        var win = isIE ?
+                currentTarget.ownerDocument.parentWindow :
+                currentTarget.ownerDocument.defaultView;
+
+        addEvent(win, "resize", this.onResize);
+        addEvent(win, "blur", this.onBlur);
+
+        var chrome = Firebug.chrome;
+
+        this.listeners = [
+            chrome.keyCodeListen("ESCAPE", null, bind(this.cancelEditing, this))
+        ];
+
+        if (editor.arrowCompletion)
+        {
+            this.listeners.push(
+                chrome.keyCodeListen("UP", null, bindFixed(editor.completeValue, editor, -1)),
+                chrome.keyCodeListen("DOWN", null, bindFixed(editor.completeValue, editor, 1)),
+                chrome.keyCodeListen("PAGE_UP", null, bindFixed(editor.completeValue, editor, -pageAmount)),
+                chrome.keyCodeListen("PAGE_DOWN", null, bindFixed(editor.completeValue, editor, pageAmount))
+            );
+        }
+
+        if (currentEditor.tabNavigation)
+        {
+            this.listeners.push(
+                chrome.keyCodeListen("RETURN", null, bind(this.tabNextEditor, this)),
+                chrome.keyCodeListen("RETURN", isControl, bind(this.insertRow, this, null, "after")),
+                chrome.keyCodeListen("TAB", null, bind(this.tabNextEditor, this)),
+                chrome.keyCodeListen("TAB", isShift, bind(this.tabPreviousEditor, this))
+            );
+        }
+        else if (currentEditor.multiLine)
+        {
+            this.listeners.push(
+                chrome.keyCodeListen("TAB", null, insertTab)
+            );
+        }
+        else
+        {
+            this.listeners.push(
+                chrome.keyCodeListen("RETURN", null, bindFixed(this.stopEditing, this))
+            );
+
+            if (currentEditor.tabCompletion)
+            {
+                this.listeners.push(
+                    chrome.keyCodeListen("TAB", null, bind(editor.completeValue, editor, 1)),
+                    chrome.keyCodeListen("TAB", isShift, bind(editor.completeValue, editor, -1))
+                );
+            }
+        }
+    },
+
+    detachListeners: function(editor, context)
+    {
+        if (!this.listeners)
+            return;
+
+        var win = isIE ?
+                currentTarget.ownerDocument.parentWindow :
+                currentTarget.ownerDocument.defaultView;
+
+        removeEvent(win, "resize", this.onResize);
+        removeEvent(win, "blur", this.onBlur);
+
+        var chrome = Firebug.chrome;
+        if (chrome)
+        {
+            for (var i = 0; i < this.listeners.length; ++i)
+                chrome.keyIgnore(this.listeners[i]);
+        }
+
+        delete this.listeners;
+    },
+
+    onResize: function(event)
+    {
+        currentEditor.layout(true);
+    },
+
+    onBlur: function(event)
+    {
+        if (currentEditor.enterOnBlur && isAncestor(event.target, currentEditor.box))
+            this.stopEditing();
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Module
+
+    initialize: function()
+    {
+        Firebug.Module.initialize.apply(this, arguments);
+
+        this.onResize = bindFixed(this.onResize, this);
+        this.onBlur = bind(this.onBlur, this);
+    },
+
+    disable: function()
+    {
+        this.stopEditing();
+    },
+
+    showContext: function(browser, context)
+    {
+        this.stopEditing();
+    },
+
+    showPanel: function(browser, panel)
+    {
+        this.stopEditing();
+    }
+});
+
+// ************************************************************************************************
+// BaseEditor
+
+Firebug.BaseEditor = extend(Firebug.MeasureBox,
+{
+    getValue: function()
+    {
+    },
+
+    setValue: function(value)
+    {
+    },
+
+    show: function(target, panel, value, textSize, targetSize)
+    {
+    },
+
+    hide: function()
+    {
+    },
+
+    layout: function(forceAll)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Support for context menus within inline editors.
+
+    getContextMenuItems: function(target)
+    {
+        var items = [];
+        items.push({label: "Cut", commandID: "cmd_cut"});
+        items.push({label: "Copy", commandID: "cmd_copy"});
+        items.push({label: "Paste", commandID: "cmd_paste"});
+        return items;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Editor Module listeners will get "onBeginEditing" just before this call
+
+    beginEditing: function(target, value)
+    {
+    },
+
+    // Editor Module listeners will get "onSaveEdit" just after this call
+    saveEdit: function(target, value, previousValue)
+    {
+    },
+
+    endEditing: function(target, value, cancel)
+    {
+        // Remove empty groups by default
+        return true;
+    },
+
+    insertNewRow: function(target, insertWhere)
+    {
+    }
+});
+
+// ************************************************************************************************
+// InlineEditor
+
+// basic inline editor attributes
+var inlineEditorAttributes = {
+    "class": "textEditorInner",
+
+    type: "text",
+    spellcheck: "false",
+
+    onkeypress: "$onKeyPress",
+
+    onoverflow: "$onOverflow",
+    oncontextmenu: "$onContextMenu"
+};
+
+// IE does not support the oninput event, so we're using the onkeydown to signalize
+// the relevant keyboard events, and the onpropertychange to actually handle the
+// input event, which should happen after the onkeydown event is fired and after the
+// value of the input is updated, but before the onkeyup and before the input (with the
+// new value) is rendered
+if (isIE)
+{
+    inlineEditorAttributes.onpropertychange = "$onInput";
+    inlineEditorAttributes.onkeydown = "$onKeyDown";
+}
+// for other browsers we use the oninput event
+else
+{
+    inlineEditorAttributes.oninput = "$onInput";
+}
+
+Firebug.InlineEditor = function(doc)
+{
+    this.initializeInline(doc);
+};
+
+Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor,
+{
+    enterOnBlur: true,
+    outerMargin: 8,
+    shadowExpand: 7,
+
+    tag:
+        DIV({"class": "inlineEditor"},
+            DIV({"class": "textEditorTop1"},
+                DIV({"class": "textEditorTop2"})
+            ),
+            DIV({"class": "textEditorInner1"},
+                DIV({"class": "textEditorInner2"},
+                    INPUT(
+                        inlineEditorAttributes
+                    )
+                )
+            ),
+            DIV({"class": "textEditorBottom1"},
+                DIV({"class": "textEditorBottom2"})
+            )
+        ),
+
+    inputTag :
+        INPUT({"class": "textEditorInner", type: "text",
+            /*oninput: "$onInput",*/ onkeypress: "$onKeyPress", onoverflow: "$onOverflow"}
+        ),
+
+    expanderTag:
+        IMG({"class": "inlineExpander", src: "blank.gif"}),
+
+    initialize: function()
+    {
+        this.fixedWidth = false;
+        this.completeAsYouType = true;
+        this.tabNavigation = true;
+        this.multiLine = false;
+        this.tabCompletion = false;
+        this.arrowCompletion = true;
+        this.noWrap = true;
+        this.numeric = false;
+    },
+
+    destroy: function()
+    {
+        this.destroyInput();
+    },
+
+    initializeInline: function(doc)
+    {
+        if (FBTrace.DBG_EDITOR)
+            FBTrace.sysout("Firebug.InlineEditor initializeInline()");
+
+        //this.box = this.tag.replace({}, doc, this);
+        this.box = this.tag.append({}, doc.body, this);
+
+        //this.input = this.box.childNodes[1].firstChild.firstChild;  // XXXjjb childNode[1] required
+        this.input = this.box.getElementsByTagName("input")[0];
+
+        if (isIElt8)
+        {
+            this.input.style.top = "-8px";
+        }
+
+        this.expander = this.expanderTag.replace({}, doc, this);
+        this.initialize();
+    },
+
+    destroyInput: function()
+    {
+        // XXXjoe Need to remove input/keypress handlers to avoid leaks
+    },
+
+    getValue: function()
+    {
+        return this.input.value;
+    },
+
+    setValue: function(value)
+    {
+        // It's only a one-line editor, so new lines shouldn't be allowed
+        return this.input.value = stripNewLines(value);
+    },
+
+    show: function(target, panel, value, targetSize)
+    {
+        //dispatch([Firebug.A11yModel], "onInlineEditorShow", [panel, this]);
+        this.target = target;
+        this.panel = panel;
+
+        this.targetSize = targetSize;
+
+        // TODO: xxxpedro editor
+        //this.targetOffset = getClientOffset(target);
+
+        // Some browsers (IE, Google Chrome and Safari) will have problem trying to get the
+        // offset values of invisible elements, or empty elements. So, in order to get the
+        // correct values, we temporary inject a character in the innerHTML of the empty element,
+        // then we get the offset values, and next, we restore the original innerHTML value.
+        var innerHTML = target.innerHTML;
+        var isEmptyElement = !innerHTML;
+        if (isEmptyElement)
+            target.innerHTML = ".";
+
+        // Get the position of the target element (that is about to be edited)
+        this.targetOffset =
+        {
+            x: target.offsetLeft,
+            y: target.offsetTop
+        };
+
+        // Restore the original innerHTML value of the empty element
+        if (isEmptyElement)
+            target.innerHTML = innerHTML;
+
+        this.originalClassName = this.box.className;
+
+        var classNames = target.className.split(" ");
+        for (var i = 0; i < classNames.length; ++i)
+            setClass(this.box, "editor-" + classNames[i]);
+
+        // Make the editor match the target's font style
+        copyTextStyles(target, this.box);
+
+        this.setValue(value);
+
+        if (this.fixedWidth)
+            this.updateLayout(true);
+        else
+        {
+            this.startMeasuring(target);
+            this.textSize = this.measureInputText(value);
+
+            // Correct the height of the box to make the funky CSS drop-shadow line up
+            var parent = this.input.parentNode;
+            if (hasClass(parent, "textEditorInner2"))
+            {
+                var yDiff = this.textSize.height - this.shadowExpand;
+
+                // IE6 height offset
+                if (isIE6)
+                    yDiff -= 2;
+
+                parent.style.height = yDiff + "px";
+                parent.parentNode.style.height = yDiff + "px";
+            }
+
+            this.updateLayout(true);
+        }
+
+        this.getAutoCompleter().reset();
+
+        if (isIElt8)
+            panel.panelNode.appendChild(this.box);
+        else
+            target.offsetParent.appendChild(this.box);
+
+        //console.log(target);
+        //this.input.select(); // it's called bellow, with setTimeout
+
+        if (isIE)
+        {
+            // reset input style
+            this.input.style.fontFamily = "Monospace";
+            this.input.style.fontSize = "11px";
+        }
+
+        // Insert the "expander" to cover the target element with white space
+        if (!this.fixedWidth)
+        {
+            copyBoxStyles(target, this.expander);
+
+            target.parentNode.replaceChild(this.expander, target);
+            collapse(target, true);
+            this.expander.parentNode.insertBefore(target, this.expander);
+        }
+
+        //TODO: xxxpedro
+        //scrollIntoCenterView(this.box, null, true);
+
+        // Display the editor after change its size and position to avoid flickering
+        this.box.style.display = "block";
+
+        // we need to call input.focus() and input.select() with a timeout,
+        // otherwise it won't work on all browsers due to timing issues
+        var self = this;
+        setTimeout(function(){
+            self.input.focus();
+            self.input.select();
+        },0);
+    },
+
+    hide: function()
+    {
+        this.box.className = this.originalClassName;
+
+        if (!this.fixedWidth)
+        {
+            this.stopMeasuring();
+
+            collapse(this.target, false);
+
+            if (this.expander.parentNode)
+                this.expander.parentNode.removeChild(this.expander);
+        }
+
+        if (this.box.parentNode)
+        {
+            ///setSelectionRange(this.input, 0, 0);
+            this.input.blur();
+
+            this.box.parentNode.removeChild(this.box);
+        }
+
+        delete this.target;
+        delete this.panel;
+    },
+
+    layout: function(forceAll)
+    {
+        if (!this.fixedWidth)
+            this.textSize = this.measureInputText(this.input.value);
+
+        if (forceAll)
+            this.targetOffset = getClientOffset(this.expander);
+
+        this.updateLayout(false, forceAll);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    beginEditing: function(target, value)
+    {
+    },
+
+    saveEdit: function(target, value, previousValue)
+    {
+    },
+
+    endEditing: function(target, value, cancel)
+    {
+        // Remove empty groups by default
+        return true;
+    },
+
+    insertNewRow: function(target, insertWhere)
+    {
+    },
+
+    advanceToNext: function(target, charCode)
+    {
+        return false;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getAutoCompleteRange: function(value, offset)
+    {
+    },
+
+    getAutoCompleteList: function(preExpr, expr, postExpr)
+    {
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getAutoCompleter: function()
+    {
+        if (!this.autoCompleter)
+        {
+            this.autoCompleter = new Firebug.AutoCompleter(null,
+                bind(this.getAutoCompleteRange, this), bind(this.getAutoCompleteList, this),
+                true, false);
+        }
+
+        return this.autoCompleter;
+    },
+
+    completeValue: function(amt)
+    {
+        //console.log("completeValue");
+
+        var selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, true, amt < 0);
+
+        if (selectRangeCallback)
+        {
+            Firebug.Editor.update(true);
+
+            // We need to select the editor text after calling update in Safari/Chrome,
+            // otherwise the text won't be selected
+            if (isSafari)
+                setTimeout(selectRangeCallback,0);
+            else
+                selectRangeCallback();
+        }
+        else
+            this.incrementValue(amt);
+    },
+
+    incrementValue: function(amt)
+    {
+        var value = this.input.value;
+
+        // TODO: xxxpedro editor
+        if (isIE)
+            var start = getInputSelectionStart(this.input), end = start;
+        else
+            var start = this.input.selectionStart, end = this.input.selectionEnd;
+
+        //debugger;
+        var range = this.getAutoCompleteRange(value, start);
+        if (!range || range.type != "int")
+            range = {start: 0, end: value.length-1};
+
+        var expr = value.substr(range.start, range.end-range.start+1);
+        preExpr = value.substr(0, range.start);
+        postExpr = value.substr(range.end+1);
+
+        // See if the value is an integer, and if so increment it
+        var intValue = parseInt(expr);
+        if (!!intValue || intValue == 0)
+        {
+            var m = /\d+/.exec(expr);
+            var digitPost = expr.substr(m.index+m[0].length);
+
+            var completion = intValue-amt;
+            this.input.value = preExpr + completion + digitPost + postExpr;
+
+            setSelectionRange(this.input, start, end);
+
+            Firebug.Editor.update(true);
+
+            return true;
+        }
+        else
+            return false;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onKeyPress: function(event)
+    {
+        //console.log("onKeyPress", event);
+        if (event.keyCode == 27 && !this.completeAsYouType)
+        {
+            var reverted = this.getAutoCompleter().revert(this.input);
+            if (reverted)
+                cancelEvent(event);
+        }
+        else if (event.charCode && this.advanceToNext(this.target, event.charCode))
+        {
+            Firebug.Editor.tabNextEditor();
+            cancelEvent(event);
+        }
+        else
+        {
+            if (this.numeric && event.charCode && (event.charCode < 48 || event.charCode > 57)
+                && event.charCode != 45 && event.charCode != 46)
+                FBL.cancelEvent(event);
+            else
+            {
+                // If the user backspaces, don't autocomplete after the upcoming input event
+                this.ignoreNextInput = event.keyCode == 8;
+            }
+        }
+    },
+
+    onOverflow: function()
+    {
+        this.updateLayout(false, false, 3);
+    },
+
+    onKeyDown: function(event)
+    {
+        //console.log("onKeyDown", event.keyCode);
+        if (event.keyCode > 46 || event.keyCode == 32 || event.keyCode == 8)
+        {
+            this.keyDownPressed = true;
+        }
+    },
+
+    onInput: function(event)
+    {
+        //debugger;
+
+        // skip not relevant onpropertychange calls on IE
+        if (isIE)
+        {
+            if (event.propertyName != "value" || !isVisible(this.input) || !this.keyDownPressed)
+                return;
+
+            this.keyDownPressed = false;
+        }
+
+        //console.log("onInput", event);
+        //console.trace();
+
+        var selectRangeCallback;
+
+        if (this.ignoreNextInput)
+        {
+            this.ignoreNextInput = false;
+            this.getAutoCompleter().reset();
+        }
+        else if (this.completeAsYouType)
+            selectRangeCallback = this.getAutoCompleter().complete(currentPanel.context, this.input, false);
+        else
+            this.getAutoCompleter().reset();
+
+        Firebug.Editor.update();
+
+        if (selectRangeCallback)
+        {
+            // We need to select the editor text after calling update in Safari/Chrome,
+            // otherwise the text won't be selected
+            if (isSafari)
+                setTimeout(selectRangeCallback,0);
+            else
+                selectRangeCallback();
+        }
+    },
+
+    onContextMenu: function(event)
+    {
+        cancelEvent(event);
+
+        var popup = $("fbInlineEditorPopup");
+        FBL.eraseNode(popup);
+
+        var target = event.target || event.srcElement;
+        var menu = this.getContextMenuItems(target);
+        if (menu)
+        {
+            for (var i = 0; i < menu.length; ++i)
+                FBL.createMenuItem(popup, menu[i]);
+        }
+
+        if (!popup.firstChild)
+            return false;
+
+        popup.openPopupAtScreen(event.screenX, event.screenY, true);
+        return true;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    updateLayout: function(initial, forceAll, extraWidth)
+    {
+        if (this.fixedWidth)
+        {
+            this.box.style.left = (this.targetOffset.x) + "px";
+            this.box.style.top = (this.targetOffset.y) + "px";
+
+            var w = this.target.offsetWidth;
+            var h = this.target.offsetHeight;
+            this.input.style.width = w + "px";
+            this.input.style.height = (h-3) + "px";
+        }
+        else
+        {
+            if (initial || forceAll)
+            {
+                this.box.style.left = this.targetOffset.x + "px";
+                this.box.style.top = this.targetOffset.y + "px";
+            }
+
+            var approxTextWidth = this.textSize.width;
+            var maxWidth = (currentPanel.panelNode.scrollWidth - this.targetOffset.x)
+                - this.outerMargin;
+
+            var wrapped = initial
+                ? this.noWrap && this.targetSize.height > this.textSize.height+3
+                : this.noWrap && approxTextWidth > maxWidth;
+
+            if (wrapped)
+            {
+                var style = isIE ?
+                        this.target.currentStyle :
+                        this.target.ownerDocument.defaultView.getComputedStyle(this.target, "");
+
+                targetMargin = parseInt(style.marginLeft) + parseInt(style.marginRight);
+
+                // Make the width fit the remaining x-space from the offset to the far right
+                approxTextWidth = maxWidth - targetMargin;
+
+                this.input.style.width = "100%";
+                this.box.style.width = approxTextWidth + "px";
+            }
+            else
+            {
+                // Make the input one character wider than the text value so that
+                // typing does not ever cause the textbox to scroll
+                var charWidth = this.measureInputText('m').width;
+
+                // Sometimes we need to make the editor a little wider, specifically when
+                // an overflow happens, otherwise it will scroll off some text on the left
+                if (extraWidth)
+                    charWidth *= extraWidth;
+
+                var inputWidth = approxTextWidth + charWidth;
+
+                if (initial)
+                {
+                    if (isIE)
+                    {
+                        // TODO: xxxpedro
+                        var xDiff = 13;
+                        this.box.style.width = (inputWidth + xDiff) + "px";
+                    }
+                    else
+                        this.box.style.width = "auto";
+                }
+                else
+                {
+                    // TODO: xxxpedro
+                    var xDiff = isIE ? 13: this.box.scrollWidth - this.input.offsetWidth;
+                    this.box.style.width = (inputWidth + xDiff) + "px";
+                }
+
+                this.input.style.width = inputWidth + "px";
+            }
+
+            this.expander.style.width = approxTextWidth + "px";
+            this.expander.style.height = Math.max(this.textSize.height-3,0) + "px";
+        }
+
+        if (forceAll)
+            scrollIntoCenterView(this.box, null, true);
+    }
+});
+
+// ************************************************************************************************
+// Autocompletion
+
+Firebug.AutoCompleter = function(getExprOffset, getRange, evaluator, selectMode, caseSensitive)
+{
+    var candidates = null;
+    var originalValue = null;
+    var originalOffset = -1;
+    var lastExpr = null;
+    var lastOffset = -1;
+    var exprOffset = 0;
+    var lastIndex = 0;
+    var preParsed = null;
+    var preExpr = null;
+    var postExpr = null;
+
+    this.revert = function(textBox)
+    {
+        if (originalOffset != -1)
+        {
+            textBox.value = originalValue;
+
+            setSelectionRange(textBox, originalOffset, originalOffset);
+
+            this.reset();
+            return true;
+        }
+        else
+        {
+            this.reset();
+            return false;
+        }
+    };
+
+    this.reset = function()
+    {
+        candidates = null;
+        originalValue = null;
+        originalOffset = -1;
+        lastExpr = null;
+        lastOffset = 0;
+        exprOffset = 0;
+    };
+
+    this.complete = function(context, textBox, cycle, reverse)
+    {
+        //console.log("complete", context, textBox, cycle, reverse);
+        // TODO: xxxpedro important port to firebug (variable leak)
+        //var value = lastValue = textBox.value;
+        var value = textBox.value;
+
+        //var offset = textBox.selectionStart;
+        var offset = getInputSelectionStart(textBox);
+
+        // The result of selectionStart() in Safari/Chrome is 1 unit less than the result
+        // in Firefox. Therefore, we need to manually adjust the value here.
+        if (isSafari && !cycle && offset >= 0) offset++;
+
+        if (!selectMode && originalOffset != -1)
+            offset = originalOffset;
+
+        if (!candidates || !cycle || offset != lastOffset)
+        {
+            originalOffset = offset;
+            originalValue = value;
+
+            // Find the part of the string that will be parsed
+            var parseStart = getExprOffset ? getExprOffset(value, offset, context) : 0;
+            preParsed = value.substr(0, parseStart);
+            var parsed = value.substr(parseStart);
+
+            // Find the part of the string that is being completed
+            var range = getRange ? getRange(parsed, offset-parseStart, context) : null;
+            if (!range)
+                range = {start: 0, end: parsed.length-1 };
+
+            var expr = parsed.substr(range.start, range.end-range.start+1);
+            preExpr = parsed.substr(0, range.start);
+            postExpr = parsed.substr(range.end+1);
+            exprOffset = parseStart + range.start;
+
+            if (!cycle)
+            {
+                if (!expr)
+                    return;
+                else if (lastExpr && lastExpr.indexOf(expr) != 0)
+                {
+                    candidates = null;
+                }
+                else if (lastExpr && lastExpr.length >= expr.length)
+                {
+                    candidates = null;
+                    lastExpr = expr;
+                    return;
+                }
+            }
+
+            lastExpr = expr;
+            lastOffset = offset;
+
+            var searchExpr;
+
+            // Check if the cursor is at the very right edge of the expression, or
+            // somewhere in the middle of it
+            if (expr && offset != parseStart+range.end+1)
+            {
+                if (cycle)
+                {
+                    // We are in the middle of the expression, but we can
+                    // complete by cycling to the next item in the values
+                    // list after the expression
+                    offset = range.start;
+                    searchExpr = expr;
+                    expr = "";
+                }
+                else
+                {
+                    // We can't complete unless we are at the ridge edge
+                    return;
+                }
+            }
+
+            var values = evaluator(preExpr, expr, postExpr, context);
+            if (!values)
+                return;
+
+            if (expr)
+            {
+                // Filter the list of values to those which begin with expr. We
+                // will then go on to complete the first value in the resulting list
+                candidates = [];
+
+                if (caseSensitive)
+                {
+                    for (var i = 0; i < values.length; ++i)
+                    {
+                        var name = values[i];
+                        if (name.indexOf && name.indexOf(expr) == 0)
+                            candidates.push(name);
+                    }
+                }
+                else
+                {
+                    var lowerExpr = caseSensitive ? expr : expr.toLowerCase();
+                    for (var i = 0; i < values.length; ++i)
+                    {
+                        var name = values[i];
+                        if (name.indexOf && name.toLowerCase().indexOf(lowerExpr) == 0)
+                            candidates.push(name);
+                    }
+                }
+
+                lastIndex = reverse ? candidates.length-1 : 0;
+            }
+            else if (searchExpr)
+            {
+                var searchIndex = -1;
+
+                // Find the first instance of searchExpr in the values list. We
+                // will then complete the string that is found
+                if (caseSensitive)
+                {
+                    searchIndex = values.indexOf(expr);
+                }
+                else
+                {
+                    var lowerExpr = searchExpr.toLowerCase();
+                    for (var i = 0; i < values.length; ++i)
+                    {
+                        var name = values[i];
+                        if (name && name.toLowerCase().indexOf(lowerExpr) == 0)
+                        {
+                            searchIndex = i;
+                            break;
+                        }
+                    }
+                }
+
+                // Nothing found, so there's nothing to complete to
+                if (searchIndex == -1)
+                    return this.reset();
+
+                expr = searchExpr;
+                candidates = cloneArray(values);
+                lastIndex = searchIndex;
+            }
+            else
+            {
+                expr = "";
+                candidates = [];
+                for (var i = 0; i < values.length; ++i)
+                {
+                    if (values[i].substr)
+                        candidates.push(values[i]);
+                }
+                lastIndex = -1;
+            }
+        }
+
+        if (cycle)
+        {
+            expr = lastExpr;
+            lastIndex += reverse ? -1 : 1;
+        }
+
+        if (!candidates.length)
+            return;
+
+        if (lastIndex >= candidates.length)
+            lastIndex = 0;
+        else if (lastIndex < 0)
+            lastIndex = candidates.length-1;
+
+        var completion = candidates[lastIndex];
+        var preCompletion = expr.substr(0, offset-exprOffset);
+        var postCompletion = completion.substr(offset-exprOffset);
+
+        textBox.value = preParsed + preExpr + preCompletion + postCompletion + postExpr;
+        var offsetEnd = preParsed.length + preExpr.length + completion.length;
+
+        // TODO: xxxpedro remove the following commented code, if the lib.setSelectionRange()
+        // is working well.
+        /*
+        if (textBox.setSelectionRange)
+        {
+            // we must select the range with a timeout, otherwise the text won't
+            // be properly selected (because after this function executes, the editor's
+            // input will be resized to fit the whole text)
+            setTimeout(function(){
+                if (selectMode)
+                    textBox.setSelectionRange(offset, offsetEnd);
+                else
+                    textBox.setSelectionRange(offsetEnd, offsetEnd);
+            },0);
+        }
+        /**/
+
+        // we must select the range with a timeout, otherwise the text won't
+        // be properly selected (because after this function executes, the editor's
+        // input will be resized to fit the whole text)
+        /*
+        setTimeout(function(){
+            if (selectMode)
+                setSelectionRange(textBox, offset, offsetEnd);
+            else
+                setSelectionRange(textBox, offsetEnd, offsetEnd);
+        },0);
+
+        return true;
+        /**/
+
+        // The editor text should be selected only after calling the editor.update()
+        // in Safari/Chrome, otherwise the text won't be selected. So, we're returning
+        // a function to be called later (in the proper time for all browsers).
+        //
+        // TODO: xxxpedro see if we can move the editor.update() calls to here, and avoid
+        // returning a closure. the complete() function seems to be called only twice in
+        // editor.js. See if this function is called anywhere else (like css.js for example).
+        return function(){
+            //console.log("autocomplete ", textBox, offset, offsetEnd);
+
+            if (selectMode)
+                setSelectionRange(textBox, offset, offsetEnd);
+            else
+                setSelectionRange(textBox, offsetEnd, offsetEnd);
+        };
+        /**/
+    };
+};
+
+// ************************************************************************************************
+// Local Helpers
+
+var getDefaultEditor = function getDefaultEditor(panel)
+{
+    if (!defaultEditor)
+    {
+        var doc = panel.document;
+        defaultEditor = new Firebug.InlineEditor(doc);
+    }
+
+    return defaultEditor;
+}
+
+/**
+ * An outsider is the first element matching the stepper element that
+ * is not an child of group. Elements tagged with insertBefore or insertAfter
+ * classes are also excluded from these results unless they are the sibling
+ * of group, relative to group's parent editGroup. This allows for the proper insertion
+ * rows when groups are nested.
+ */
+var getOutsider = function getOutsider(element, group, stepper)
+{
+    var parentGroup = getAncestorByClass(group.parentNode, "editGroup");
+    var next;
+    do
+    {
+        next = stepper(next || element);
+    }
+    while (isAncestor(next, group) || isGroupInsert(next, parentGroup));
+
+    return next;
+}
+
+var isGroupInsert = function isGroupInsert(next, group)
+{
+    return (!group || isAncestor(next, group))
+        && (hasClass(next, "insertBefore") || hasClass(next, "insertAfter"));
+}
+
+var getNextOutsider = function getNextOutsider(element, group)
+{
+    return getOutsider(element, group, bind(getNextByClass, FBL, "editable"));
+}
+
+var getPreviousOutsider = function getPreviousOutsider(element, group)
+{
+    return getOutsider(element, group, bind(getPreviousByClass, FBL, "editable"));
+}
+
+var getInlineParent = function getInlineParent(element)
+{
+    var lastInline = element;
+    for (; element; element = element.parentNode)
+    {
+        //var s = element.ownerDocument.defaultView.getComputedStyle(element, "");
+        var s = isIE ?
+                element.currentStyle :
+                element.ownerDocument.defaultView.getComputedStyle(element, "");
+
+        if (s.display != "inline")
+            return lastInline;
+        else
+            lastInline = element;
+    }
+    return null;
+}
+
+var insertTab = function insertTab()
+{
+    insertTextIntoElement(currentEditor.input, Firebug.Editor.tabCharacter);
+}
+
+// ************************************************************************************************
+
+Firebug.registerModule(Firebug.Editor);
+
+// ************************************************************************************************
+
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+if (Env.Options.disableXHRListener)
+    return;
+
+// ************************************************************************************************
+// XHRSpy
+
+var XHRSpy = function()
+{
+    this.requestHeaders = [];
+    this.responseHeaders = [];
+};
+
+XHRSpy.prototype =
+{
+    method: null,
+    url: null,
+    async: null,
+
+    xhrRequest: null,
+
+    href: null,
+
+    loaded: false,
+
+    logRow: null,
+
+    responseText: null,
+
+    requestHeaders: null,
+    responseHeaders: null,
+
+    sourceLink: null, // {href:"file.html", line: 22}
+
+    getURL: function()
+    {
+        return this.href;
+    }
+};
+
+// ************************************************************************************************
+// XMLHttpRequestWrapper
+
+var XMLHttpRequestWrapper = function(activeXObject)
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // XMLHttpRequestWrapper internal variables
+
+    var xhrRequest = typeof activeXObject != "undefined" ?
+                activeXObject :
+                new _XMLHttpRequest(),
+
+        spy = new XHRSpy(),
+
+        self = this,
+
+        reqType,
+        reqUrl,
+        reqStartTS;
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // XMLHttpRequestWrapper internal methods
+
+    var updateSelfPropertiesIgnore = {
+        abort: 1,
+        channel: 1,
+        getAllResponseHeaders: 1,
+        getInterface: 1,
+        getResponseHeader: 1,
+        mozBackgroundRequest: 1,
+        multipart: 1,
+        onreadystatechange: 1,
+        open: 1,
+        send: 1,
+        setRequestHeader: 1
+    };
+
+    var updateSelfProperties = function()
+    {
+        if (supportsXHRIterator)
+        {
+            for (var propName in xhrRequest)
+            {
+                if (propName in updateSelfPropertiesIgnore)
+                    continue;
+
+                try
+                {
+                    var propValue = xhrRequest[propName];
+
+                    if (propValue && !isFunction(propValue))
+                        self[propName] = propValue;
+                }
+                catch(E)
+                {
+                    //console.log(propName, E.message);
+                }
+            }
+        }
+        else
+        {
+            // will fail to read these xhrRequest properties if the request is not completed
+            if (xhrRequest.readyState == 4)
+            {
+                self.status = xhrRequest.status;
+                self.statusText = xhrRequest.statusText;
+                self.responseText = xhrRequest.responseText;
+                self.responseXML = xhrRequest.responseXML;
+            }
+        }
+    };
+
+    var updateXHRPropertiesIgnore = {
+        channel: 1,
+        onreadystatechange: 1,
+        readyState: 1,
+        responseBody: 1,
+        responseText: 1,
+        responseXML: 1,
+        status: 1,
+        statusText: 1,
+        upload: 1
+    };
+
+    var updateXHRProperties = function()
+    {
+        for (var propName in self)
+        {
+            if (propName in updateXHRPropertiesIgnore)
+                continue;
+
+            try
+            {
+                var propValue = self[propName];
+
+                if (propValue && !xhrRequest[propName])
+                {
+                    xhrRequest[propName] = propValue;
+                }
+            }
+            catch(E)
+            {
+                //console.log(propName, E.message);
+            }
+        }
+    };
+
+    var logXHR = function()
+    {
+        var row = Firebug.Console.log(spy, null, "spy", Firebug.Spy.XHR);
+
+        if (row)
+        {
+            setClass(row, "loading");
+            spy.logRow = row;
+        }
+    };
+
+    var finishXHR = function()
+    {
+        var duration = new Date().getTime() - reqStartTS;
+        var success = xhrRequest.status == 200;
+
+        var responseHeadersText = xhrRequest.getAllResponseHeaders();
+        var responses = responseHeadersText ? responseHeadersText.split(/[\n\r]/) : [];
+        var reHeader = /^(\S+):\s*(.*)/;
+
+        for (var i=0, l=responses.length; i<l; i++)
+        {
+            var text = responses[i];
+            var match = text.match(reHeader);
+
+            if (match)
+            {
+                var name = match[1];
+                var value = match[2];
+
+                // update the spy mimeType property so we can detect when to show
+                // custom response viewers (such as HTML, XML or JSON viewer)
+                if (name == "Content-Type")
+                    spy.mimeType = value;
+
+                /*
+                if (name == "Last Modified")
+                {
+                    if (!spy.cacheEntry)
+                        spy.cacheEntry = [];
+
+                    spy.cacheEntry.push({
+                       name: [name],
+                       value: [value]
+                    });
+                }
+                /**/
+
+                spy.responseHeaders.push({
+                   name: [name],
+                   value: [value]
+                });
+            }
+        }
+
+        with({
+            row: spy.logRow,
+            status: xhrRequest.status == 0 ?
+                        // if xhrRequest.status == 0 then accessing xhrRequest.statusText
+                        // will cause an error, so we must handle this case (Issue 3504)
+                        "" : xhrRequest.status + " " + xhrRequest.statusText,
+            time: duration,
+            success: success
+        })
+        {
+            setTimeout(function(){
+
+                spy.responseText = xhrRequest.responseText;
+
+                // update row information to avoid "ethernal spinning gif" bug in IE
+                row = row || spy.logRow;
+
+                // if chrome document is not loaded, there will be no row yet, so just ignore
+                if (!row) return;
+
+                // update the XHR representation data
+                handleRequestStatus(success, status, time);
+
+            },200);
+        }
+
+        spy.loaded = true;
+        /*
+        // commented because they are being updated by the updateSelfProperties() function
+        self.status = xhrRequest.status;
+        self.statusText = xhrRequest.statusText;
+        self.responseText = xhrRequest.responseText;
+        self.responseXML = xhrRequest.responseXML;
+        /**/
+        updateSelfProperties();
+    };
+
+    var handleStateChange = function()
+    {
+        //Firebug.Console.log(["onreadystatechange", xhrRequest.readyState, xhrRequest.readyState == 4 && xhrRequest.status]);
+
+        self.readyState = xhrRequest.readyState;
+
+        if (xhrRequest.readyState == 4)
+        {
+            finishXHR();
+
+            xhrRequest.onreadystatechange = function(){};
+        }
+
+        //Firebug.Console.log(spy.url + ": " + xhrRequest.readyState);
+
+        self.onreadystatechange();
+    };
+
+    // update the XHR representation data
+    var handleRequestStatus = function(success, status, time)
+    {
+        var row = spy.logRow;
+        FBL.removeClass(row, "loading");
+
+        if (!success)
+            FBL.setClass(row, "error");
+
+        var item = FBL.$$(".spyStatus", row)[0];
+        item.innerHTML = status;
+
+        if (time)
+        {
+            var item = FBL.$$(".spyTime", row)[0];
+            item.innerHTML = time + "ms";
+        }
+    };
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // XMLHttpRequestWrapper public properties and handlers
+
+    this.readyState = 0;
+
+    this.onreadystatechange = function(){};
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // XMLHttpRequestWrapper public methods
+
+    this.open = function(method, url, async, user, password)
+    {
+        //Firebug.Console.log("xhrRequest open");
+
+        updateSelfProperties();
+
+        if (spy.loaded)
+            spy = new XHRSpy();
+
+        spy.method = method;
+        spy.url = url;
+        spy.async = async;
+        spy.href = url;
+        spy.xhrRequest = xhrRequest;
+        spy.urlParams = parseURLParamsArray(url);
+
+        try
+        {
+            // xhrRequest.open.apply may not be available in IE
+            if (supportsApply)
+                xhrRequest.open.apply(xhrRequest, arguments);
+            else
+                xhrRequest.open(method, url, async, user, password);
+        }
+        catch(e)
+        {
+        }
+
+        xhrRequest.onreadystatechange = handleStateChange;
+
+    };
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    this.send = function(data)
+    {
+        //Firebug.Console.log("xhrRequest send");
+        spy.data = data;
+
+        reqStartTS = new Date().getTime();
+
+        updateXHRProperties();
+
+        try
+        {
+            xhrRequest.send(data);
+        }
+        catch(e)
+        {
+            // TODO: xxxpedro XHR throws or not?
+            //throw e;
+        }
+        finally
+        {
+            logXHR();
+
+            if (!spy.async)
+            {
+                self.readyState = xhrRequest.readyState;
+
+                // sometimes an error happens when calling finishXHR()
+                // Issue 3422: Firebug Lite breaks Google Instant Search
+                try
+                {
+                    finishXHR();
+                }
+                catch(E)
+                {
+                }
+            }
+        }
+    };
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    this.setRequestHeader = function(header, value)
+    {
+        spy.requestHeaders.push({name: [header], value: [value]});
+        return xhrRequest.setRequestHeader(header, value);
+    };
+
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    this.abort = function()
+    {
+        xhrRequest.abort();
+        updateSelfProperties();
+        handleRequestStatus(false, "Aborted");
+    };
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    this.getResponseHeader = function(header)
+    {
+        return xhrRequest.getResponseHeader(header);
+    };
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    this.getAllResponseHeaders = function()
+    {
+        return xhrRequest.getAllResponseHeaders();
+    };
+
+    /**/
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Clone XHR object
+
+    // xhrRequest.open.apply not available in IE and will throw an error in
+    // IE6 by simply reading xhrRequest.open so we must sniff it
+    var supportsApply = !isIE6 &&
+            xhrRequest &&
+            xhrRequest.open &&
+            typeof xhrRequest.open.apply != "undefined";
+
+    var numberOfXHRProperties = 0;
+    for (var propName in xhrRequest)
+    {
+        numberOfXHRProperties++;
+
+        if (propName in updateSelfPropertiesIgnore)
+            continue;
+
+        try
+        {
+            var propValue = xhrRequest[propName];
+
+            if (isFunction(propValue))
+            {
+                if (typeof self[propName] == "undefined")
+                {
+                    this[propName] = (function(name, xhr){
+
+                        return supportsApply ?
+                            // if the browser supports apply
+                            function()
+                            {
+                                return xhr[name].apply(xhr, arguments);
+                            }
+                            :
+                            function(a,b,c,d,e)
+                            {
+                                return xhr[name](a,b,c,d,e);
+                            };
+
+                    })(propName, xhrRequest);
+                }
+            }
+            else
+                this[propName] = propValue;
+        }
+        catch(E)
+        {
+            //console.log(propName, E.message);
+        }
+    }
+
+    // IE6 does not support for (var prop in XHR)
+    var supportsXHRIterator = numberOfXHRProperties > 0;
+
+    /**/
+
+    return this;
+};
+
+// ************************************************************************************************
+// ActiveXObject Wrapper (IE6 only)
+
+var _ActiveXObject;
+var isIE6 =  /msie 6/i.test(navigator.appVersion);
+
+if (isIE6)
+{
+    _ActiveXObject = window.ActiveXObject;
+
+    var xhrObjects = " MSXML2.XMLHTTP.5.0 MSXML2.XMLHTTP.4.0 MSXML2.XMLHTTP.3.0 MSXML2.XMLHTTP Microsoft.XMLHTTP ";
+
+    window.ActiveXObject = function(name)
+    {
+        var error = null;
+
+        try
+        {
+            var activeXObject = new _ActiveXObject(name);
+        }
+        catch(e)
+        {
+            error = e;
+        }
+        finally
+        {
+            if (!error)
+            {
+                if (xhrObjects.indexOf(" " + name + " ") != -1)
+                    return new XMLHttpRequestWrapper(activeXObject);
+                else
+                    return activeXObject;
+            }
+            else
+                throw error.message;
+        }
+    };
+}
+
+// ************************************************************************************************
+
+// Register the XMLHttpRequestWrapper for non-IE6 browsers
+if (!isIE6)
+{
+    var _XMLHttpRequest = XMLHttpRequest;
+    window.XMLHttpRequest = function()
+    {
+        return new XMLHttpRequestWrapper();
+    };
+}
+
+//************************************************************************************************
+
+FBL.getNativeXHRObject = function()
+{
+    var xhrObj = false;
+    try
+    {
+        xhrObj = new _XMLHttpRequest();
+    }
+    catch(e)
+    {
+        var progid = [
+                "MSXML2.XMLHTTP.5.0", "MSXML2.XMLHTTP.4.0",
+                "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"
+            ];
+
+        for ( var i=0; i < progid.length; ++i ) {
+            try
+            {
+                xhrObj = new _ActiveXObject(progid[i]);
+            }
+            catch(e)
+            {
+                continue;
+            }
+            break;
+        }
+    }
+    finally
+    {
+        return xhrObj;
+    }
+};
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var reIgnore = /about:|javascript:|resource:|chrome:|jar:/;
+var layoutInterval = 300;
+var indentWidth = 18;
+
+var cacheSession = null;
+var contexts = new Array();
+var panelName = "net";
+var maxQueueRequests = 500;
+//var panelBar1 = $("fbPanelBar1"); // chrome not available at startup
+var activeRequests = [];
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var mimeExtensionMap =
+{
+    "txt": "text/plain",
+    "html": "text/html",
+    "htm": "text/html",
+    "xhtml": "text/html",
+    "xml": "text/xml",
+    "css": "text/css",
+    "js": "application/x-javascript",
+    "jss": "application/x-javascript",
+    "jpg": "image/jpg",
+    "jpeg": "image/jpeg",
+    "gif": "image/gif",
+    "png": "image/png",
+    "bmp": "image/bmp",
+    "swf": "application/x-shockwave-flash",
+    "flv": "video/x-flv"
+};
+
+var fileCategories =
+{
+    "undefined": 1,
+    "html": 1,
+    "css": 1,
+    "js": 1,
+    "xhr": 1,
+    "image": 1,
+    "flash": 1,
+    "txt": 1,
+    "bin": 1
+};
+
+var textFileCategories =
+{
+    "txt": 1,
+    "html": 1,
+    "xhr": 1,
+    "css": 1,
+    "js": 1
+};
+
+var binaryFileCategories =
+{
+    "bin": 1,
+    "flash": 1
+};
+
+var mimeCategoryMap =
+{
+    "text/plain": "txt",
+    "application/octet-stream": "bin",
+    "text/html": "html",
+    "text/xml": "html",
+    "text/css": "css",
+    "application/x-javascript": "js",
+    "text/javascript": "js",
+    "application/javascript" : "js",
+    "image/jpeg": "image",
+    "image/jpg": "image",
+    "image/gif": "image",
+    "image/png": "image",
+    "image/bmp": "image",
+    "application/x-shockwave-flash": "flash",
+    "video/x-flv": "flash"
+};
+
+var binaryCategoryMap =
+{
+    "image": 1,
+    "flash" : 1
+};
+
+// ************************************************************************************************
+
+/**
+ * @module Represents a module object for the Net panel. This object is derived
+ * from <code>Firebug.ActivableModule</code> in order to support activation (enable/disable).
+ * This allows to avoid (performance) expensive features if the functionality is not necessary
+ * for the user.
+ */
+Firebug.NetMonitor = extend(Firebug.ActivableModule,
+{
+    dispatchName: "netMonitor",
+
+    clear: function(context)
+    {
+        // The user pressed a Clear button so, remove content of the panel...
+        var panel = context.getPanel(panelName, true);
+        if (panel)
+            panel.clear();
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Module
+
+    initialize: function()
+    {
+        return;
+
+        this.panelName = panelName;
+
+        Firebug.ActivableModule.initialize.apply(this, arguments);
+
+        if (Firebug.TraceModule)
+            Firebug.TraceModule.addListener(this.TraceListener);
+
+        // HTTP observer must be registered now (and not in monitorContext, since if a
+        // page is opened in a new tab the top document request would be missed otherwise.
+        NetHttpObserver.registerObserver();
+        NetHttpActivityObserver.registerObserver();
+
+        Firebug.Debugger.addListener(this.DebuggerListener);
+    },
+
+    shutdown: function()
+    {
+        return;
+
+        prefs.removeObserver(Firebug.prefDomain, this, false);
+        if (Firebug.TraceModule)
+            Firebug.TraceModule.removeListener(this.TraceListener);
+
+        NetHttpObserver.unregisterObserver();
+        NetHttpActivityObserver.unregisterObserver();
+
+        Firebug.Debugger.removeListener(this.DebuggerListener);
+    }
+});
+
+
+/**
+ * @domplate Represents a template that is used to reneder detailed info about a request.
+ * This template is rendered when a request is expanded.
+ */
+Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(),
+{
+    tag:
+        DIV({"class": "netInfoBody", _repObject: "$file"},
+            TAG("$infoTabs", {file: "$file"}),
+            TAG("$infoBodies", {file: "$file"})
+        ),
+
+    infoTabs:
+        DIV({"class": "netInfoTabs focusRow subFocusRow", "role": "tablist"},
+            A({"class": "netInfoParamsTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+                view: "Params",
+                $collapsed: "$file|hideParams"},
+                $STR("URLParameters")
+            ),
+            A({"class": "netInfoHeadersTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+                view: "Headers"},
+                $STR("Headers")
+            ),
+            A({"class": "netInfoPostTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+                view: "Post",
+                $collapsed: "$file|hidePost"},
+                $STR("Post")
+            ),
+            A({"class": "netInfoPutTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+                view: "Put",
+                $collapsed: "$file|hidePut"},
+                $STR("Put")
+            ),
+            A({"class": "netInfoResponseTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+                view: "Response",
+                $collapsed: "$file|hideResponse"},
+                $STR("Response")
+            ),
+            A({"class": "netInfoCacheTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+               view: "Cache",
+               $collapsed: "$file|hideCache"},
+               $STR("Cache")
+            ),
+            A({"class": "netInfoHtmlTab netInfoTab a11yFocus", onclick: "$onClickTab", "role": "tab",
+               view: "Html",
+               $collapsed: "$file|hideHtml"},
+               $STR("HTML")
+            )
+        ),
+
+    infoBodies:
+        DIV({"class": "netInfoBodies outerFocusRow"},
+            TABLE({"class": "netInfoParamsText netInfoText netInfoParamsTable", "role": "tabpanel",
+                    cellpadding: 0, cellspacing: 0}, TBODY()),
+            DIV({"class": "netInfoHeadersText netInfoText", "role": "tabpanel"}),
+            DIV({"class": "netInfoPostText netInfoText", "role": "tabpanel"}),
+            DIV({"class": "netInfoPutText netInfoText", "role": "tabpanel"}),
+            PRE({"class": "netInfoResponseText netInfoText", "role": "tabpanel"}),
+            DIV({"class": "netInfoCacheText netInfoText", "role": "tabpanel"},
+                TABLE({"class": "netInfoCacheTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
+                    TBODY({"role": "list", "aria-label": $STR("Cache")})
+                )
+            ),
+            DIV({"class": "netInfoHtmlText netInfoText", "role": "tabpanel"},
+                IFRAME({"class": "netInfoHtmlPreview", "role": "document"})
+            )
+        ),
+
+    headerDataTag:
+        FOR("param", "$headers",
+            TR({"role": "listitem"},
+                TD({"class": "netInfoParamName", "role": "presentation"},
+                    TAG("$param|getNameTag", {param: "$param"})
+                ),
+                TD({"class": "netInfoParamValue", "role": "list", "aria-label": "$param.name"},
+                    FOR("line", "$param|getParamValueIterator",
+                        CODE({"class": "focusRow subFocusRow", "role": "listitem"}, "$line")
+                    )
+                )
+            )
+        ),
+
+    customTab:
+        A({"class": "netInfo$tabId\\Tab netInfoTab", onclick: "$onClickTab", view: "$tabId", "role": "tab"},
+            "$tabTitle"
+        ),
+
+    customBody:
+        DIV({"class": "netInfo$tabId\\Text netInfoText", "role": "tabpanel"}),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    nameTag:
+        SPAN("$param|getParamName"),
+
+    nameWithTooltipTag:
+        SPAN({title: "$param.name"}, "$param|getParamName"),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getNameTag: function(param)
+    {
+        return (this.getParamName(param) == param.name) ? this.nameTag : this.nameWithTooltipTag;
+    },
+
+    getParamName: function(param)
+    {
+        var limit = 25;
+        var name = param.name;
+        if (name.length > limit)
+            name = name.substr(0, limit) + "...";
+        return name;
+    },
+
+    getParamTitle: function(param)
+    {
+        var limit = 25;
+        var name = param.name;
+        if (name.length > limit)
+            return name;
+        return "";
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    hideParams: function(file)
+    {
+        return !file.urlParams || !file.urlParams.length;
+    },
+
+    hidePost: function(file)
+    {
+        return file.method.toUpperCase() != "POST";
+    },
+
+    hidePut: function(file)
+    {
+        return file.method.toUpperCase() != "PUT";
+    },
+
+    hideResponse: function(file)
+    {
+        return false;
+        //return file.category in binaryFileCategories;
+    },
+
+    hideCache: function(file)
+    {
+        return true;
+        //xxxHonza: I don't see any reason why not to display the cache also info for images.
+        return !file.cacheEntry; // || file.category=="image";
+    },
+
+    hideHtml: function(file)
+    {
+        return (file.mimeType != "text/html") && (file.mimeType != "application/xhtml+xml");
+    },
+
+    onClickTab: function(event)
+    {
+        this.selectTab(event.currentTarget || event.srcElement);
+    },
+
+    getParamValueIterator: function(param)
+    {
+        // TODO: xxxpedro console2
+        return param.value;
+
+        // This value is inserted into CODE element and so, make sure the HTML isn't escaped (1210).
+        // This is why the second parameter is true.
+        // The CODE (with style white-space:pre) element preserves whitespaces so they are
+        // displayed the same, as they come from the server (1194).
+        // In case of a long header values of post parameters the value must be wrapped (2105).
+        return wrapText(param.value, true);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    appendTab: function(netInfoBox, tabId, tabTitle)
+    {
+        // Create new tab and body.
+        var args = {tabId: tabId, tabTitle: tabTitle};
+        ///this.customTab.append(args, netInfoBox.getElementsByClassName("netInfoTabs").item(0));
+        ///this.customBody.append(args, netInfoBox.getElementsByClassName("netInfoBodies").item(0));
+        this.customTab.append(args, $$(".netInfoTabs", netInfoBox)[0]);
+        this.customBody.append(args, $$(".netInfoBodies", netInfoBox)[0]);
+    },
+
+    selectTabByName: function(netInfoBox, tabName)
+    {
+        var tab = getChildByClass(netInfoBox, "netInfoTabs", "netInfo"+tabName+"Tab");
+        if (tab)
+            this.selectTab(tab);
+    },
+
+    selectTab: function(tab)
+    {
+        var view = tab.getAttribute("view");
+
+        var netInfoBox = getAncestorByClass(tab, "netInfoBody");
+
+        var selectedTab = netInfoBox.selectedTab;
+
+        if (selectedTab)
+        {
+            //netInfoBox.selectedText.removeAttribute("selected");
+            removeClass(netInfoBox.selectedText, "netInfoTextSelected");
+
+            removeClass(selectedTab, "netInfoTabSelected");
+            //selectedTab.removeAttribute("selected");
+            selectedTab.setAttribute("aria-selected", "false");
+        }
+
+        var textBodyName = "netInfo" + view + "Text";
+
+        selectedTab = netInfoBox.selectedTab = tab;
+
+        netInfoBox.selectedText = $$("."+textBodyName, netInfoBox)[0];
+        //netInfoBox.selectedText = netInfoBox.getElementsByClassName(textBodyName).item(0);
+
+        //netInfoBox.selectedText.setAttribute("selected", "true");
+        setClass(netInfoBox.selectedText, "netInfoTextSelected");
+
+        setClass(selectedTab, "netInfoTabSelected");
+        selectedTab.setAttribute("selected", "true");
+        selectedTab.setAttribute("aria-selected", "true");
+
+        var file = Firebug.getRepObject(netInfoBox);
+
+        //var context = Firebug.getElementPanel(netInfoBox).context;
+        var context = Firebug.chrome;
+
+        this.updateInfo(netInfoBox, file, context);
+    },
+
+    updateInfo: function(netInfoBox, file, context)
+    {
+        if (FBTrace.DBG_NET)
+            FBTrace.sysout("net.updateInfo; file", file);
+
+        if (!netInfoBox)
+        {
+            if (FBTrace.DBG_NET || FBTrace.DBG_ERRORS)
+                FBTrace.sysout("net.updateInfo; ERROR netInfo == null " + file.href, file);
+            return;
+        }
+
+        var tab = netInfoBox.selectedTab;
+
+        if (hasClass(tab, "netInfoParamsTab"))
+        {
+            if (file.urlParams && !netInfoBox.urlParamsPresented)
+            {
+                netInfoBox.urlParamsPresented = true;
+                this.insertHeaderRows(netInfoBox, file.urlParams, "Params");
+            }
+        }
+
+        else if (hasClass(tab, "netInfoHeadersTab"))
+        {
+            var headersText = $$(".netInfoHeadersText", netInfoBox)[0];
+            //var headersText = netInfoBox.getElementsByClassName("netInfoHeadersText").item(0);
+
+            if (file.responseHeaders && !netInfoBox.responseHeadersPresented)
+            {
+                netInfoBox.responseHeadersPresented = true;
+                NetInfoHeaders.renderHeaders(headersText, file.responseHeaders, "ResponseHeaders");
+            }
+
+            if (file.requestHeaders && !netInfoBox.requestHeadersPresented)
+            {
+                netInfoBox.requestHeadersPresented = true;
+                NetInfoHeaders.renderHeaders(headersText, file.requestHeaders, "RequestHeaders");
+            }
+        }
+
+        else if (hasClass(tab, "netInfoPostTab"))
+        {
+            if (!netInfoBox.postPresented)
+            {
+                netInfoBox.postPresented  = true;
+                //var postText = netInfoBox.getElementsByClassName("netInfoPostText").item(0);
+                var postText = $$(".netInfoPostText", netInfoBox)[0];
+                NetInfoPostData.render(context, postText, file);
+            }
+        }
+
+        else if (hasClass(tab, "netInfoPutTab"))
+        {
+            if (!netInfoBox.putPresented)
+            {
+                netInfoBox.putPresented  = true;
+                //var putText = netInfoBox.getElementsByClassName("netInfoPutText").item(0);
+                var putText = $$(".netInfoPutText", netInfoBox)[0];
+                NetInfoPostData.render(context, putText, file);
+            }
+        }
+
+        else if (hasClass(tab, "netInfoResponseTab") && file.loaded && !netInfoBox.responsePresented)
+        {
+            ///var responseTextBox = netInfoBox.getElementsByClassName("netInfoResponseText").item(0);
+            var responseTextBox = $$(".netInfoResponseText", netInfoBox)[0];
+            if (file.category == "image")
+            {
+                netInfoBox.responsePresented = true;
+
+                var responseImage = netInfoBox.ownerDocument.createElement("img");
+                responseImage.src = file.href;
+
+                clearNode(responseTextBox);
+                responseTextBox.appendChild(responseImage, responseTextBox);
+            }
+            else ///if (!(binaryCategoryMap.hasOwnProperty(file.category)))
+            {
+                this.setResponseText(file, netInfoBox, responseTextBox, context);
+            }
+        }
+
+        else if (hasClass(tab, "netInfoCacheTab") && file.loaded && !netInfoBox.cachePresented)
+        {
+            var responseTextBox = netInfoBox.getElementsByClassName("netInfoCacheText").item(0);
+            if (file.cacheEntry) {
+                netInfoBox.cachePresented = true;
+                this.insertHeaderRows(netInfoBox, file.cacheEntry, "Cache");
+            }
+        }
+
+        else if (hasClass(tab, "netInfoHtmlTab") && file.loaded && !netInfoBox.htmlPresented)
+        {
+            netInfoBox.htmlPresented = true;
+
+            var text = Utils.getResponseText(file, context);
+
+            ///var iframe = netInfoBox.getElementsByClassName("netInfoHtmlPreview").item(0);
+            var iframe = $$(".netInfoHtmlPreview", netInfoBox)[0];
+
+            ///iframe.contentWindow.document.body.innerHTML = text;
+
+            // TODO: xxxpedro net - remove scripts
+            var reScript = /<script(.|\s)*?\/script>/gi;
+
+            text = text.replace(reScript, "");
+
+            iframe.contentWindow.document.write(text);
+            iframe.contentWindow.document.close();
+        }
+
+        // Notify listeners about update so, content of custom tabs can be updated.
+        dispatch(NetInfoBody.fbListeners, "updateTabBody", [netInfoBox, file, context]);
+    },
+
+    setResponseText: function(file, netInfoBox, responseTextBox, context)
+    {
+        //**********************************************
+        //**********************************************
+        //**********************************************
+        netInfoBox.responsePresented = true;
+        // line breaks somehow are different in IE
+        // make this only once in the initialization? we don't have net panels and modules yet.
+        if (isIE)
+            responseTextBox.style.whiteSpace = "nowrap";
+
+        responseTextBox[
+                typeof responseTextBox.textContent != "undefined" ?
+                        "textContent" :
+                        "innerText"
+            ] = file.responseText;
+
+        return;
+        //**********************************************
+        //**********************************************
+        //**********************************************
+
+        // Get response text and make sure it doesn't exceed the max limit.
+        var text = Utils.getResponseText(file, context);
+        var limit = Firebug.netDisplayedResponseLimit + 15;
+        var limitReached = text ? (text.length > limit) : false;
+        if (limitReached)
+            text = text.substr(0, limit) + "...";
+
+        // Insert the response into the UI.
+        if (text)
+            insertWrappedText(text, responseTextBox);
+        else
+            insertWrappedText("", responseTextBox);
+
+        // Append a message informing the user that the response isn't fully displayed.
+        if (limitReached)
+        {
+            var object = {
+                text: $STR("net.responseSizeLimitMessage"),
+                onClickLink: function() {
+                    var panel = context.getPanel("net", true);
+                    panel.openResponseInTab(file);
+                }
+            };
+            Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox);
+        }
+
+        netInfoBox.responsePresented = true;
+
+        if (FBTrace.DBG_NET)
+            FBTrace.sysout("net.setResponseText; response text updated");
+    },
+
+    insertHeaderRows: function(netInfoBox, headers, tableName, rowName)
+    {
+        if (!headers.length)
+            return;
+
+        var headersTable = $$(".netInfo"+tableName+"Table", netInfoBox)[0];
+        //var headersTable = netInfoBox.getElementsByClassName("netInfo"+tableName+"Table").item(0);
+        var tbody = getChildByClass(headersTable, "netInfo" + rowName + "Body");
+        if (!tbody)
+            tbody = headersTable.firstChild;
+        var titleRow = getChildByClass(tbody, "netInfo" + rowName + "Title");
+
+        this.headerDataTag.insertRows({headers: headers}, titleRow ? titleRow : tbody);
+        removeClass(titleRow, "collapsed");
+    }
+});
+
+var NetInfoBody = Firebug.NetMonitor.NetInfoBody;
+
+// ************************************************************************************************
+
+/**
+ * @domplate Used within the Net panel to display raw source of request and response headers
+ * as well as pretty-formatted summary of these headers.
+ */
+Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, //new Firebug.Listener(),
+{
+    tag:
+        DIV({"class": "netInfoHeadersTable", "role": "tabpanel"},
+            DIV({"class": "netInfoHeadersGroup netInfoResponseHeadersTitle"},
+                SPAN($STR("ResponseHeaders")),
+                SPAN({"class": "netHeadersViewSource response collapsed", onclick: "$onViewSource",
+                    _sourceDisplayed: false, _rowName: "ResponseHeaders"},
+                    $STR("net.headers.view source")
+                )
+            ),
+            TABLE({cellpadding: 0, cellspacing: 0},
+                TBODY({"class": "netInfoResponseHeadersBody", "role": "list",
+                    "aria-label": $STR("ResponseHeaders")})
+            ),
+            DIV({"class": "netInfoHeadersGroup netInfoRequestHeadersTitle"},
+                SPAN($STR("RequestHeaders")),
+                SPAN({"class": "netHeadersViewSource request collapsed", onclick: "$onViewSource",
+                    _sourceDisplayed: false, _rowName: "RequestHeaders"},
+                    $STR("net.headers.view source")
+                )
+            ),
+            TABLE({cellpadding: 0, cellspacing: 0},
+                TBODY({"class": "netInfoRequestHeadersBody", "role": "list",
+                    "aria-label": $STR("RequestHeaders")})
+            )
+        ),
+
+    sourceTag:
+        TR({"role": "presentation"},
+            TD({colspan: 2, "role": "presentation"},
+                PRE({"class": "source"})
+            )
+        ),
+
+    onViewSource: function(event)
+    {
+        var target = event.target;
+        var requestHeaders = (target.rowName == "RequestHeaders");
+
+        var netInfoBox = getAncestorByClass(target, "netInfoBody");
+        var file = netInfoBox.repObject;
+
+        if (target.sourceDisplayed)
+        {
+            var headers = requestHeaders ? file.requestHeaders : file.responseHeaders;
+            this.insertHeaderRows(netInfoBox, headers, target.rowName);
+            target.innerHTML = $STR("net.headers.view source");
+        }
+        else
+        {
+            var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText;
+            this.insertSource(netInfoBox, source, target.rowName);
+            target.innerHTML = $STR("net.headers.pretty print");
+        }
+
+        target.sourceDisplayed = !target.sourceDisplayed;
+
+        cancelEvent(event);
+    },
+
+    insertSource: function(netInfoBox, source, rowName)
+    {
+        // This breaks copy to clipboard.
+        //if (source)
+        //    source = source.replace(/\r\n/gm, "<span style='color:lightgray'>\\r\\n</span>\r\n");
+
+        ///var tbody = netInfoBox.getElementsByClassName("netInfo" + rowName + "Body").item(0);
+        var tbody = $$(".netInfo" + rowName + "Body", netInfoBox)[0];
+        var node = this.sourceTag.replace({}, tbody);
+        ///var sourceNode = node.getElementsByClassName("source").item(0);
+        var sourceNode = $$(".source", node)[0];
+        sourceNode.innerHTML = source;
+    },
+
+    insertHeaderRows: function(netInfoBox, headers, rowName)
+    {
+        var headersTable = $$(".netInfoHeadersTable", netInfoBox)[0];
+        var tbody = $$(".netInfo" + rowName + "Body", headersTable)[0];
+
+        //var headersTable = netInfoBox.getElementsByClassName("netInfoHeadersTable").item(0);
+        //var tbody = headersTable.getElementsByClassName("netInfo" + rowName + "Body").item(0);
+
+        clearNode(tbody);
+
+        if (!headers.length)
+            return;
+
+        NetInfoBody.headerDataTag.insertRows({headers: headers}, tbody);
+
+        var titleRow = getChildByClass(headersTable, "netInfo" + rowName + "Title");
+        removeClass(titleRow, "collapsed");
+    },
+
+    init: function(parent)
+    {
+        var rootNode = this.tag.append({}, parent);
+
+        var netInfoBox = getAncestorByClass(parent, "netInfoBody");
+        var file = netInfoBox.repObject;
+
+        var viewSource;
+
+        viewSource = $$(".request", rootNode)[0];
+        //viewSource = rootNode.getElementsByClassName("netHeadersViewSource request").item(0);
+        if (file.requestHeadersText)
+            removeClass(viewSource, "collapsed");
+
+        viewSource = $$(".response", rootNode)[0];
+        //viewSource = rootNode.getElementsByClassName("netHeadersViewSource response").item(0);
+        if (file.responseHeadersText)
+            removeClass(viewSource, "collapsed");
+    },
+
+    renderHeaders: function(parent, headers, rowName)
+    {
+        if (!parent.firstChild)
+            this.init(parent);
+
+        this.insertHeaderRows(parent, headers, rowName);
+    }
+});
+
+var NetInfoHeaders = Firebug.NetMonitor.NetInfoHeaders;
+
+// ************************************************************************************************
+
+/**
+ * @domplate Represents posted data within request info (the info, which is visible when
+ * a request entry is expanded. This template renders content of the Post tab.
+ */
+Firebug.NetMonitor.NetInfoPostData = domplate(Firebug.Rep, /*new Firebug.Listener(),*/
+{
+    // application/x-www-form-urlencoded
+    paramsTable:
+        TABLE({"class": "netInfoPostParamsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
+            TBODY({"role": "list", "aria-label": $STR("net.label.Parameters")},
+                TR({"class": "netInfoPostParamsTitle", "role": "presentation"},
+                    TD({colspan: 3, "role": "presentation"},
+                        DIV({"class": "netInfoPostParams"},
+                            $STR("net.label.Parameters"),
+                            SPAN({"class": "netInfoPostContentType"},
+                                "application/x-www-form-urlencoded"
+                            )
+                        )
+                    )
+                )
+            )
+        ),
+
+    // multipart/form-data
+    partsTable:
+        TABLE({"class": "netInfoPostPartsTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
+            TBODY({"role": "list", "aria-label": $STR("net.label.Parts")},
+                TR({"class": "netInfoPostPartsTitle", "role": "presentation"},
+                    TD({colspan: 2, "role":"presentation" },
+                        DIV({"class": "netInfoPostParams"},
+                            $STR("net.label.Parts"),
+                            SPAN({"class": "netInfoPostContentType"},
+                                "multipart/form-data"
+                            )
+                        )
+                    )
+                )
+            )
+        ),
+
+    // application/json
+    jsonTable:
+        TABLE({"class": "netInfoPostJSONTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
+            ///TBODY({"role": "list", "aria-label": $STR("jsonviewer.tab.JSON")},
+            TBODY({"role": "list", "aria-label": $STR("JSON")},
+                TR({"class": "netInfoPostJSONTitle", "role": "presentation"},
+                    TD({"role": "presentation" },
+                        DIV({"class": "netInfoPostParams"},
+                            ///$STR("jsonviewer.tab.JSON")
+                            $STR("JSON")
+                        )
+                    )
+                ),
+                TR(
+                    TD({"class": "netInfoPostJSONBody"})
+                )
+            )
+        ),
+
+    // application/xml
+    xmlTable:
+        TABLE({"class": "netInfoPostXMLTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
+            TBODY({"role": "list", "aria-label": $STR("xmlviewer.tab.XML")},
+                TR({"class": "netInfoPostXMLTitle", "role": "presentation"},
+                    TD({"role": "presentation" },
+                        DIV({"class": "netInfoPostParams"},
+                            $STR("xmlviewer.tab.XML")
+                        )
+                    )
+                ),
+                TR(
+                    TD({"class": "netInfoPostXMLBody"})
+                )
+            )
+        ),
+
+    sourceTable:
+        TABLE({"class": "netInfoPostSourceTable", cellpadding: 0, cellspacing: 0, "role": "presentation"},
+            TBODY({"role": "list", "aria-label": $STR("net.label.Source")},
+                TR({"class": "netInfoPostSourceTitle", "role": "presentation"},
+                    TD({colspan: 2, "role": "presentation"},
+                        DIV({"class": "netInfoPostSource"},
+                            $STR("net.label.Source")
+                        )
+                    )
+                )
+            )
+        ),
+
+    sourceBodyTag:
+        TR({"role": "presentation"},
+            TD({colspan: 2, "role": "presentation"},
+                FOR("line", "$param|getParamValueIterator",
+                    CODE({"class":"focusRow subFocusRow" , "role": "listitem"},"$line")
+                )
+            )
+        ),
+
+    getParamValueIterator: function(param)
+    {
+        return NetInfoBody.getParamValueIterator(param);
+    },
+
+    render: function(context, parentNode, file)
+    {
+        //debugger;
+        var spy = getAncestorByClass(parentNode, "spyHead");
+        var spyObject = spy.repObject;
+        var data = spyObject.data;
+
+        ///var contentType = Utils.findHeader(file.requestHeaders, "content-type");
+        var contentType = file.mimeType;
+
+        ///var text = Utils.getPostText(file, context, true);
+        ///if (text == undefined)
+        ///    return;
+
+        ///if (Utils.isURLEncodedRequest(file, context))
+        // fake Utils.isURLEncodedRequest identification
+        if (contentType && contentType == "application/x-www-form-urlencoded" ||
+            data && data.indexOf("=") != -1)
+        {
+            ///var lines = text.split("\n");
+            ///var params = parseURLEncodedText(lines[lines.length-1]);
+            var params = parseURLEncodedTextArray(data);
+            if (params)
+                this.insertParameters(parentNode, params);
+        }
+
+        ///if (Utils.isMultiPartRequest(file, context))
+        ///{
+        ///    var data = this.parseMultiPartText(file, context);
+        ///    if (data)
+        ///        this.insertParts(parentNode, data);
+        ///}
+
+        // moved to the top
+        ///var contentType = Utils.findHeader(file.requestHeaders, "content-type");
+
+        ///if (Firebug.JSONViewerModel.isJSON(contentType))
+        var jsonData = {
+            responseText: data
+        };
+
+        if (Firebug.JSONViewerModel.isJSON(contentType, data))
+            ///this.insertJSON(parentNode, file, context);
+            this.insertJSON(parentNode, jsonData, context);
+
+        ///if (Firebug.XMLViewerModel.isXML(contentType))
+        ///    this.insertXML(parentNode, file, context);
+
+        ///var postText = Utils.getPostText(file, context);
+        ///postText = Utils.formatPostText(postText);
+        var postText = data;
+        if (postText)
+            this.insertSource(parentNode, postText);
+    },
+
+    insertParameters: function(parentNode, params)
+    {
+        if (!params || !params.length)
+            return;
+
+        var paramTable = this.paramsTable.append({object:{}}, parentNode);
+        var row = $$(".netInfoPostParamsTitle", paramTable)[0];
+        //var paramTable = this.paramsTable.append(null, parentNode);
+        //var row = paramTable.getElementsByClassName("netInfoPostParamsTitle").item(0);
+
+        var tbody = paramTable.getElementsByTagName("tbody")[0];
+
+        NetInfoBody.headerDataTag.insertRows({headers: params}, row);
+    },
+
+    insertParts: function(parentNode, data)
+    {
+        if (!data.params || !data.params.length)
+            return;
+
+        var partsTable = this.partsTable.append({object:{}}, parentNode);
+        var row = $$(".netInfoPostPartsTitle", paramTable)[0];
+        //var partsTable = this.partsTable.append(null, parentNode);
+        //var row = partsTable.getElementsByClassName("netInfoPostPartsTitle").item(0);
+
+        NetInfoBody.headerDataTag.insertRows({headers: data.params}, row);
+    },
+
+    insertJSON: function(parentNode, file, context)
+    {
+        ///var text = Utils.getPostText(file, context);
+        var text = file.responseText;
+        ///var data = parseJSONString(text, "http://" + file.request.originalURI.host);
+        var data = parseJSONString(text);
+        if (!data)
+            return;
+
+        ///var jsonTable = this.jsonTable.append(null, parentNode);
+        var jsonTable = this.jsonTable.append({}, parentNode);
+        ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostJSONBody").item(0);
+        var jsonBody = $$(".netInfoPostJSONBody", jsonTable)[0];
+
+        if (!this.toggles)
+            this.toggles = {};
+
+        Firebug.DOMPanel.DirTable.tag.replace(
+            {object: data, toggles: this.toggles}, jsonBody);
+    },
+
+    insertXML: function(parentNode, file, context)
+    {
+        var text = Utils.getPostText(file, context);
+
+        var jsonTable = this.xmlTable.append(null, parentNode);
+        ///var jsonBody = jsonTable.getElementsByClassName("netInfoPostXMLBody").item(0);
+        var jsonBody = $$(".netInfoPostXMLBody", jsonTable)[0];
+
+        Firebug.XMLViewerModel.insertXML(jsonBody, text);
+    },
+
+    insertSource: function(parentNode, text)
+    {
+        var sourceTable = this.sourceTable.append({object:{}}, parentNode);
+        var row = $$(".netInfoPostSourceTitle", sourceTable)[0];
+        //var sourceTable = this.sourceTable.append(null, parentNode);
+        //var row = sourceTable.getElementsByClassName("netInfoPostSourceTitle").item(0);
+
+        var param = {value: [text]};
+        this.sourceBodyTag.insertRows({param: param}, row);
+    },
+
+    parseMultiPartText: function(file, context)
+    {
+        var text = Utils.getPostText(file, context);
+        if (text == undefined)
+            return null;
+
+        FBTrace.sysout("net.parseMultiPartText; boundary: ", text);
+
+        var boundary = text.match(/\s*boundary=\s*(.*)/)[1];
+
+        var divider = "\r\n\r\n";
+        var bodyStart = text.indexOf(divider);
+        var body = text.substr(bodyStart + divider.length);
+
+        var postData = {};
+        postData.mimeType = "multipart/form-data";
+        postData.params = [];
+
+        var parts = body.split("--" + boundary);
+        for (var i=0; i<parts.length; i++)
+        {
+            var part = parts[i].split(divider);
+            if (part.length != 2)
+                continue;
+
+            var m = part[0].match(/\s*name=\"(.*)\"(;|$)/);
+            postData.params.push({
+                name: (m && m.length > 1) ? m[1] : "",
+                value: trim(part[1])
+            });
+        }
+
+        return postData;
+    }
+});
+
+var NetInfoPostData = Firebug.NetMonitor.NetInfoPostData;
+
+// ************************************************************************************************
+
+
+// TODO: xxxpedro net i18n
+var $STRP = function(a){return a;};
+
+Firebug.NetMonitor.NetLimit = domplate(Firebug.Rep,
+{
+    collapsed: true,
+
+    tableTag:
+        DIV(
+            TABLE({width: "100%", cellpadding: 0, cellspacing: 0},
+                TBODY()
+            )
+        ),
+
+    limitTag:
+        TR({"class": "netRow netLimitRow", $collapsed: "$isCollapsed"},
+            TD({"class": "netCol netLimitCol", colspan: 6},
+                TABLE({cellpadding: 0, cellspacing: 0},
+                    TBODY(
+                        TR(
+                            TD(
+                                SPAN({"class": "netLimitLabel"},
+                                    $STRP("plural.Limit_Exceeded", [0])
+                                )
+                            ),
+                            TD({style: "width:100%"}),
+                            TD(
+                                BUTTON({"class": "netLimitButton", title: "$limitPrefsTitle",
+                                    onclick: "$onPreferences"},
+                                  $STR("LimitPrefs")
+                                )
+                            ),
+                            TD("&nbsp;")
+                        )
+                    )
+                )
+            )
+        ),
+
+    isCollapsed: function()
+    {
+        return this.collapsed;
+    },
+
+    onPreferences: function(event)
+    {
+        openNewTab("about:config");
+    },
+
+    updateCounter: function(row)
+    {
+        removeClass(row, "collapsed");
+
+        // Update info within the limit row.
+        var limitLabel = row.getElementsByClassName("netLimitLabel").item(0);
+        limitLabel.firstChild.nodeValue = $STRP("plural.Limit_Exceeded", [row.limitInfo.totalCount]);
+    },
+
+    createTable: function(parent, limitInfo)
+    {
+        var table = this.tableTag.replace({}, parent);
+        var row = this.createRow(table.firstChild.firstChild, limitInfo);
+        return [table, row];
+    },
+
+    createRow: function(parent, limitInfo)
+    {
+        var row = this.limitTag.insertRows(limitInfo, parent, this)[0];
+        row.limitInfo = limitInfo;
+        return row;
+    },
+
+    // nsIPrefObserver
+    observe: function(subject, topic, data)
+    {
+        // We're observing preferences only.
+        if (topic != "nsPref:changed")
+          return;
+
+        if (data.indexOf("net.logLimit") != -1)
+            this.updateMaxLimit();
+    },
+
+    updateMaxLimit: function()
+    {
+        var value = Firebug.getPref(Firebug.prefDomain, "net.logLimit");
+        maxQueueRequests = value ? value : maxQueueRequests;
+    }
+});
+
+var NetLimit = Firebug.NetMonitor.NetLimit;
+
+// ************************************************************************************************
+
+Firebug.NetMonitor.ResponseSizeLimit = domplate(Firebug.Rep,
+{
+    tag:
+        DIV({"class": "netInfoResponseSizeLimit"},
+            SPAN("$object.beforeLink"),
+            A({"class": "objectLink", onclick: "$onClickLink"},
+                "$object.linkText"
+            ),
+            SPAN("$object.afterLink")
+        ),
+
+    reLink: /^(.*)<a>(.*)<\/a>(.*$)/,
+    append: function(obj, parent)
+    {
+        var m = obj.text.match(this.reLink);
+        return this.tag.append({onClickLink: obj.onClickLink,
+            object: {
+            beforeLink: m[1],
+            linkText: m[2],
+            afterLink: m[3]
+        }}, parent, this);
+    }
+});
+
+// ************************************************************************************************
+// ************************************************************************************************
+
+Firebug.NetMonitor.Utils =
+{
+    findHeader: function(headers, name)
+    {
+        if (!headers)
+            return null;
+
+        name = name.toLowerCase();
+        for (var i = 0; i < headers.length; ++i)
+        {
+            var headerName = headers[i].name.toLowerCase();
+            if (headerName == name)
+                return headers[i].value;
+        }
+    },
+
+    formatPostText: function(text)
+    {
+        if (text instanceof XMLDocument)
+            return getElementXML(text.documentElement);
+        else
+            return text;
+    },
+
+    getPostText: function(file, context, noLimit)
+    {
+        if (!file.postText)
+        {
+            file.postText = readPostTextFromRequest(file.request, context);
+
+            if (!file.postText && context)
+                file.postText = readPostTextFromPage(file.href, context);
+        }
+
+        if (!file.postText)
+            return file.postText;
+
+        var limit = Firebug.netDisplayedPostBodyLimit;
+        if (file.postText.length > limit && !noLimit)
+        {
+            return cropString(file.postText, limit,
+                "\n\n... " + $STR("net.postDataSizeLimitMessage") + " ...\n\n");
+        }
+
+        return file.postText;
+    },
+
+    getResponseText: function(file, context)
+    {
+        // The response can be also empty string so, check agains "undefined".
+        return (typeof(file.responseText) != "undefined")? file.responseText :
+            context.sourceCache.loadText(file.href, file.method, file);
+    },
+
+    isURLEncodedRequest: function(file, context)
+    {
+        var text = Utils.getPostText(file, context);
+        if (text && text.toLowerCase().indexOf("content-type: application/x-www-form-urlencoded") == 0)
+            return true;
+
+        // The header value doesn't have to be always exactly "application/x-www-form-urlencoded",
+        // there can be even charset specified. So, use indexOf rather than just "==".
+        var headerValue = Utils.findHeader(file.requestHeaders, "content-type");
+        if (headerValue && headerValue.indexOf("application/x-www-form-urlencoded") == 0)
+            return true;
+
+        return false;
+    },
+
+    isMultiPartRequest: function(file, context)
+    {
+        var text = Utils.getPostText(file, context);
+        if (text && text.toLowerCase().indexOf("content-type: multipart/form-data") == 0)
+            return true;
+        return false;
+    },
+
+    getMimeType: function(mimeType, uri)
+    {
+        if (!mimeType || !(mimeCategoryMap.hasOwnProperty(mimeType)))
+        {
+            var ext = getFileExtension(uri);
+            if (!ext)
+                return mimeType;
+            else
+            {
+                var extMimeType = mimeExtensionMap[ext.toLowerCase()];
+                return extMimeType ? extMimeType : mimeType;
+            }
+        }
+        else
+            return mimeType;
+    },
+
+    getDateFromSeconds: function(s)
+    {
+        var d = new Date();
+        d.setTime(s*1000);
+        return d;
+    },
+
+    getHttpHeaders: function(request, file)
+    {
+        try
+        {
+            var http = QI(request, Ci.nsIHttpChannel);
+            file.status = request.responseStatus;
+
+            // xxxHonza: is there any problem to do this in requestedFile method?
+            file.method = http.requestMethod;
+            file.urlParams = parseURLParams(file.href);
+            file.mimeType = Utils.getMimeType(request.contentType, request.name);
+
+            if (!file.responseHeaders && Firebug.collectHttpHeaders)
+            {
+                var requestHeaders = [], responseHeaders = [];
+
+                http.visitRequestHeaders({
+                    visitHeader: function(name, value)
+                    {
+                        requestHeaders.push({name: name, value: value});
+                    }
+                });
+                http.visitResponseHeaders({
+                    visitHeader: function(name, value)
+                    {
+                        responseHeaders.push({name: name, value: value});
+                    }
+                });
+
+                file.requestHeaders = requestHeaders;
+                file.responseHeaders = responseHeaders;
+            }
+        }
+        catch (exc)
+        {
+            // An exception can be throwed e.g. when the request is aborted and
+            // request.responseStatus is accessed.
+            if (FBTrace.DBG_ERRORS)
+                FBTrace.sysout("net.getHttpHeaders FAILS " + file.href, exc);
+        }
+    },
+
+    isXHR: function(request)
+    {
+        try
+        {
+            var callbacks = request.notificationCallbacks;
+            var xhrRequest = callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null;
+            if (FBTrace.DBG_NET)
+                FBTrace.sysout("net.isXHR; " + (xhrRequest != null) + ", " + safeGetName(request));
+
+            return (xhrRequest != null);
+        }
+        catch (exc)
+        {
+        }
+
+       return false;
+    },
+
+    getFileCategory: function(file)
+    {
+        if (file.category)
+        {
+            if (FBTrace.DBG_NET)
+                FBTrace.sysout("net.getFileCategory; current: " + file.category + " for: " + file.href, file);
+            return file.category;
+        }
+
+        if (file.isXHR)
+        {
+            if (FBTrace.DBG_NET)
+                FBTrace.sysout("net.getFileCategory; XHR for: " + file.href, file);
+            return file.category = "xhr";
+        }
+
+        if (!file.mimeType)
+        {
+            var ext = getFileExtension(file.href);
+            if (ext)
+                file.mimeType = mimeExtensionMap[ext.toLowerCase()];
+        }
+
+        /*if (FBTrace.DBG_NET)
+            FBTrace.sysout("net.getFileCategory; " + mimeCategoryMap[file.mimeType] +
+                ", mimeType: " + file.mimeType + " for: " + file.href, file);*/
+
+        if (!file.mimeType)
+            return "";
+
+        // Solve cases when charset is also specified, eg "text/html; charset=UTF-8".
+        var mimeType = file.mimeType;
+        if (mimeType)
+            mimeType = mimeType.split(";")[0];
+
+        return (file.category = mimeCategoryMap[mimeType]);
+    }
+};
+
+var Utils = Firebug.NetMonitor.Utils;
+
+// ************************************************************************************************
+
+//Firebug.registerRep(Firebug.NetMonitor.NetRequestTable);
+//Firebug.registerActivableModule(Firebug.NetMonitor);
+//Firebug.registerPanel(NetPanel);
+
+Firebug.registerModule(Firebug.NetMonitor);
+//Firebug.registerRep(Firebug.NetMonitor.BreakpointRep);
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// Constants
+
+//const Cc = Components.classes;
+//const Ci = Components.interfaces;
+
+// List of contexts with XHR spy attached.
+var contexts = [];
+
+// ************************************************************************************************
+// Spy Module
+
+/**
+ * @module Represents a XHR Spy module. The main purpose of the XHR Spy feature is to monitor
+ * XHR activity of the current page and create appropriate log into the Console panel.
+ * This feature can be controlled by an option <i>Show XMLHttpRequests</i> (from within the
+ * console panel).
+ *
+ * The module is responsible for attaching/detaching a HTTP Observers when Firebug is
+ * activated/deactivated for a site.
+ */
+Firebug.Spy = extend(Firebug.Module,
+/** @lends Firebug.Spy */
+{
+    dispatchName: "spy",
+
+    initialize: function()
+    {
+        if (Firebug.TraceModule)
+            Firebug.TraceModule.addListener(this.TraceListener);
+
+        Firebug.Module.initialize.apply(this, arguments);
+    },
+
+    shutdown: function()
+    {
+        Firebug.Module.shutdown.apply(this, arguments);
+
+        if (Firebug.TraceModule)
+            Firebug.TraceModule.removeListener(this.TraceListener);
+    },
+
+    initContext: function(context)
+    {
+        context.spies = [];
+
+        if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled())
+            this.attachObserver(context, context.window);
+
+        if (FBTrace.DBG_SPY)
+            FBTrace.sysout("spy.initContext " + contexts.length + " ", context.getName());
+    },
+
+    destroyContext: function(context)
+    {
+        // For any spies that are in progress, remove our listeners so that they don't leak
+        this.detachObserver(context, null);
+
+        if (FBTrace.DBG_SPY && context.spies.length)
+            FBTrace.sysout("spy.destroyContext; ERROR There are leaking Spies ("
+                + context.spies.length + ") " + context.getName());
+
+        delete context.spies;
+
+        if (FBTrace.DBG_SPY)
+            FBTrace.sysout("spy.destroyContext " + contexts.length + " ", context.getName());
+    },
+
+    watchWindow: function(context, win)
+    {
+        if (Firebug.showXMLHttpRequests && Firebug.Console.isAlwaysEnabled())
+            this.attachObserver(context, win);
+    },
+
+    unwatchWindow: function(context, win)
+    {
+        try
+        {
+            // This make sure that the existing context is properly removed from "contexts" array.
+            this.detachObserver(context, win);
+        }
+        catch (ex)
+        {
+            // Get exceptions here sometimes, so let's just ignore them
+            // since the window is going away anyhow
+            ERROR(ex);
+        }
+    },
+
+    updateOption: function(name, value)
+    {
+        // XXXjjb Honza, if Console.isEnabled(context) false, then this can't be called,
+        // but somehow seems not correct
+        if (name == "showXMLHttpRequests")
+        {
+            var tach = value ? this.attachObserver : this.detachObserver;
+            for (var i = 0; i < TabWatcher.contexts.length; ++i)
+            {
+                var context = TabWatcher.contexts[i];
+                iterateWindows(context.window, function(win)
+                {
+                    tach.apply(this, [context, win]);
+                });
+            }
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Attaching Spy to XHR requests.
+
+    /**
+     * Returns false if Spy should not be attached to XHRs executed by the specified window.
+     */
+    skipSpy: function(win)
+    {
+        if (!win)
+            return true;
+
+        // Don't attach spy to chrome.
+        var uri = safeGetWindowLocation(win);
+        if (uri && (uri.indexOf("about:") == 0 || uri.indexOf("chrome:") == 0))
+            return true;
+    },
+
+    attachObserver: function(context, win)
+    {
+        if (Firebug.Spy.skipSpy(win))
+            return;
+
+        for (var i=0; i<contexts.length; ++i)
+        {
+            if ((contexts[i].context == context) && (contexts[i].win == win))
+                return;
+        }
+
+        // Register HTTP observers only once.
+        if (contexts.length == 0)
+        {
+            httpObserver.addObserver(SpyHttpObserver, "firebug-http-event", false);
+            SpyHttpActivityObserver.registerObserver();
+        }
+
+        contexts.push({context: context, win: win});
+
+        if (FBTrace.DBG_SPY)
+            FBTrace.sysout("spy.attachObserver (HTTP) " + contexts.length + " ", context.getName());
+    },
+
+    detachObserver: function(context, win)
+    {
+        for (var i=0; i<contexts.length; ++i)
+        {
+            if (contexts[i].context == context)
+            {
+                if (win && (contexts[i].win != win))
+                    continue;
+
+                contexts.splice(i, 1);
+
+                // If no context is using spy, remvove the (only one) HTTP observer.
+                if (contexts.length == 0)
+                {
+                    httpObserver.removeObserver(SpyHttpObserver, "firebug-http-event");
+                    SpyHttpActivityObserver.unregisterObserver();
+                }
+
+                if (FBTrace.DBG_SPY)
+                    FBTrace.sysout("spy.detachObserver (HTTP) " + contexts.length + " ",
+                        context.getName());
+                return;
+            }
+        }
+    },
+
+    /**
+     * Return XHR object that is associated with specified request <i>nsIHttpChannel</i>.
+     * Returns null if the request doesn't represent XHR.
+     */
+    getXHR: function(request)
+    {
+        // Does also query-interface for nsIHttpChannel.
+        if (!(request instanceof Ci.nsIHttpChannel))
+            return null;
+
+        try
+        {
+            var callbacks = request.notificationCallbacks;
+            return (callbacks ? callbacks.getInterface(Ci.nsIXMLHttpRequest) : null);
+        }
+        catch (exc)
+        {
+            if (exc.name == "NS_NOINTERFACE")
+            {
+                if (FBTrace.DBG_SPY)
+                    FBTrace.sysout("spy.getXHR; Request is not nsIXMLHttpRequest: " +
+                        safeGetRequestName(request));
+            }
+        }
+
+       return null;
+    }
+});
+
+
+
+
+
+// ************************************************************************************************
+
+/*
+function getSpyForXHR(request, xhrRequest, context, noCreate)
+{
+    var spy = null;
+
+    // Iterate all existing spy objects in this context and look for one that is
+    // already created for this request.
+    var length = context.spies.length;
+    for (var i=0; i<length; i++)
+    {
+        spy = context.spies[i];
+        if (spy.request == request)
+            return spy;
+    }
+
+    if (noCreate)
+        return null;
+
+    spy = new Firebug.Spy.XMLHttpRequestSpy(request, xhrRequest, context);
+    context.spies.push(spy);
+
+    var name = request.URI.asciiSpec;
+    var origName = request.originalURI.asciiSpec;
+
+    // Attach spy only to the original request. Notice that there can be more network requests
+    // made by the same XHR if redirects are involved.
+    if (name == origName)
+        spy.attach();
+
+    if (FBTrace.DBG_SPY)
+        FBTrace.sysout("spy.getSpyForXHR; New spy object created (" +
+            (name == origName ? "new XHR" : "redirected XHR") + ") for: " + name, spy);
+
+    return spy;
+}
+/**/
+
+// ************************************************************************************************
+
+/**
+ * @class This class represents a Spy object that is attached to XHR. This object
+ * registers various listeners into the XHR in order to monitor various events fired
+ * during the request process (onLoad, onAbort, etc.)
+ */
+/*
+Firebug.Spy.XMLHttpRequestSpy = function(request, xhrRequest, context)
+{
+    this.request = request;
+    this.xhrRequest = xhrRequest;
+    this.context = context;
+    this.responseText = "";
+
+    // For compatibility with the Net templates.
+    this.isXHR = true;
+
+    // Support for activity-observer
+    this.transactionStarted = false;
+    this.transactionClosed = false;
+};
+/**/
+
+//Firebug.Spy.XMLHttpRequestSpy.prototype =
+/** @lends Firebug.Spy.XMLHttpRequestSpy */
+/*
+{
+    attach: function()
+    {
+        var spy = this;
+        this.onReadyStateChange = function(event) { onHTTPSpyReadyStateChange(spy, event); };
+        this.onLoad = function() { onHTTPSpyLoad(spy); };
+        this.onError = function() { onHTTPSpyError(spy); };
+        this.onAbort = function() { onHTTPSpyAbort(spy); };
+
+        // xxxHonza: #502959 is still failing on Fx 3.5
+        // Use activity distributor to identify 3.6
+        if (SpyHttpActivityObserver.getActivityDistributor())
+        {
+            this.onreadystatechange = this.xhrRequest.onreadystatechange;
+            this.xhrRequest.onreadystatechange = this.onReadyStateChange;
+        }
+
+        this.xhrRequest.addEventListener("load", this.onLoad, false);
+        this.xhrRequest.addEventListener("error", this.onError, false);
+        this.xhrRequest.addEventListener("abort", this.onAbort, false);
+
+        // xxxHonza: should be removed from FB 3.6
+        if (!SpyHttpActivityObserver.getActivityDistributor())
+            this.context.sourceCache.addListener(this);
+    },
+
+    detach: function()
+    {
+        // Bubble out if already detached.
+        if (!this.onLoad)
+            return;
+
+        // If the activity distributor is available, let's detach it when the XHR
+        // transaction is closed. Since, in case of multipart XHRs the onLoad method
+        // (readyState == 4) can be called mutliple times.
+        // Keep in mind:
+        // 1) It can happen that that the TRANSACTION_CLOSE event comes before
+        // the onLoad (if the XHR is made as part of the page load) so, detach if
+        // it's already closed.
+        // 2) In case of immediate cache responses, the transaction doesn't have to
+        // be started at all (or the activity observer is no available in Firefox 3.5).
+        // So, also detach in this case.
+        if (this.transactionStarted && !this.transactionClosed)
+            return;
+
+        if (FBTrace.DBG_SPY)
+            FBTrace.sysout("spy.detach; " + this.href);
+
+        // Remove itself from the list of active spies.
+        remove(this.context.spies, this);
+
+        if (this.onreadystatechange)
+            this.xhrRequest.onreadystatechange = this.onreadystatechange;
+
+        try { this.xhrRequest.removeEventListener("load", this.onLoad, false); } catch (e) {}
+        try { this.xhrRequest.removeEventListener("error", this.onError, false); } catch (e) {}
+        try { this.xhrRequest.removeEventListener("abort", this.onAbort, false); } catch (e) {}
+
+        this.onreadystatechange = null;
+        this.onLoad = null;
+        this.onError = null;
+        this.onAbort = null;
+
+        // xxxHonza: shouuld be removed from FB 1.6
+        if (!SpyHttpActivityObserver.getActivityDistributor())
+            this.context.sourceCache.removeListener(this);
+    },
+
+    getURL: function()
+    {
+        return this.xhrRequest.channel ? this.xhrRequest.channel.name : this.href;
+    },
+
+    // Cache listener
+    onStopRequest: function(context, request, responseText)
+    {
+        if (!responseText)
+            return;
+
+        if (request == this.request)
+            this.responseText = responseText;
+    },
+};
+/**/
+// ************************************************************************************************
+/*
+function onHTTPSpyReadyStateChange(spy, event)
+{
+    if (FBTrace.DBG_SPY)
+        FBTrace.sysout("spy.onHTTPSpyReadyStateChange " + spy.xhrRequest.readyState +
+            " (multipart: " + spy.xhrRequest.multipart + ")");
+
+    // Remember just in case spy is detached (readyState == 4).
+    var originalHandler = spy.onreadystatechange;
+
+    // Force response text to be updated in the UI (in case the console entry
+    // has been already expanded and the response tab selected).
+    if (spy.logRow && spy.xhrRequest.readyState >= 3)
+    {
+        var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody");
+        if (netInfoBox)
+        {
+            netInfoBox.htmlPresented = false;
+            netInfoBox.responsePresented = false;
+        }
+    }
+
+    // If the request is loading update the end time.
+    if (spy.xhrRequest.readyState == 3)
+    {
+        spy.responseTime = spy.endTime - spy.sendTime;
+        updateTime(spy);
+    }
+
+    // Request loaded. Get all the info from the request now, just in case the
+    // XHR would be aborted in the original onReadyStateChange handler.
+    if (spy.xhrRequest.readyState == 4)
+    {
+        // Cumulate response so, multipart response content is properly displayed.
+        if (SpyHttpActivityObserver.getActivityDistributor())
+            spy.responseText += spy.xhrRequest.responseText;
+        else
+        {
+            // xxxHonza: remove from FB 1.6
+            if (!spy.responseText)
+                spy.responseText = spy.xhrRequest.responseText;
+        }
+
+        // The XHR is loaded now (used also by the activity observer).
+        spy.loaded = true;
+
+        // Update UI.
+        updateHttpSpyInfo(spy);
+
+        // Notify Net pane about a request beeing loaded.
+        // xxxHonza: I don't think this is necessary.
+        var netProgress = spy.context.netProgress;
+        if (netProgress)
+            netProgress.post(netProgress.stopFile, [spy.request, spy.endTime, spy.postText, spy.responseText]);
+
+        // Notify registered listeners about finish of the XHR.
+        dispatch(Firebug.Spy.fbListeners, "onLoad", [spy.context, spy]);
+    }
+
+    // Pass the event to the original page handler.
+    callPageHandler(spy, event, originalHandler);
+}
+
+function onHTTPSpyLoad(spy)
+{
+    if (FBTrace.DBG_SPY)
+        FBTrace.sysout("spy.onHTTPSpyLoad: " + spy.href, spy);
+
+    // Detach must be done in onLoad (not in onreadystatechange) otherwise
+    // onAbort would not be handled.
+    spy.detach();
+
+    // xxxHonza: Still needed for Fx 3.5 (#502959)
+    if (!SpyHttpActivityObserver.getActivityDistributor())
+        onHTTPSpyReadyStateChange(spy, null);
+}
+
+function onHTTPSpyError(spy)
+{
+    if (FBTrace.DBG_SPY)
+        FBTrace.sysout("spy.onHTTPSpyError; " + spy.href, spy);
+
+    spy.detach();
+    spy.loaded = true;
+
+    if (spy.logRow)
+    {
+        removeClass(spy.logRow, "loading");
+        setClass(spy.logRow, "error");
+    }
+}
+
+function onHTTPSpyAbort(spy)
+{
+    if (FBTrace.DBG_SPY)
+        FBTrace.sysout("spy.onHTTPSpyAbort: " + spy.href, spy);
+
+    spy.detach();
+    spy.loaded = true;
+
+    if (spy.logRow)
+    {
+        removeClass(spy.logRow, "loading");
+        setClass(spy.logRow, "error");
+    }
+
+    spy.statusText = "Aborted";
+    updateLogRow(spy);
+
+    // Notify Net pane about a request beeing aborted.
+    // xxxHonza: the net panel shoud find out this itself.
+    var netProgress = spy.context.netProgress;
+    if (netProgress)
+        netProgress.post(netProgress.abortFile, [spy.request, spy.endTime, spy.postText, spy.responseText]);
+}
+/**/
+
+// ************************************************************************************************
+
+/**
+ * @domplate Represents a template for XHRs logged in the Console panel. The body of the
+ * log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}.
+ */
+
+Firebug.Spy.XHR = domplate(Firebug.Rep,
+/** @lends Firebug.Spy.XHR */
+
+{
+    tag:
+        DIV({"class": "spyHead", _repObject: "$object"},
+            TABLE({"class": "spyHeadTable focusRow outerFocusRow", cellpadding: 0, cellspacing: 0,
+                "role": "listitem", "aria-expanded": "false"},
+                TBODY({"role": "presentation"},
+                    TR({"class": "spyRow"},
+                        TD({"class": "spyTitleCol spyCol", onclick: "$onToggleBody"},
+                            DIV({"class": "spyTitle"},
+                                "$object|getCaption"
+                            ),
+                            DIV({"class": "spyFullTitle spyTitle"},
+                                "$object|getFullUri"
+                            )
+                        ),
+                        TD({"class": "spyCol"},
+                            DIV({"class": "spyStatus"}, "$object|getStatus")
+                        ),
+                        TD({"class": "spyCol"},
+                            SPAN({"class": "spyIcon"})
+                        ),
+                        TD({"class": "spyCol"},
+                            SPAN({"class": "spyTime"})
+                        ),
+                        TD({"class": "spyCol"},
+                            TAG(FirebugReps.SourceLink.tag, {object: "$object.sourceLink"})
+                        )
+                    )
+                )
+            )
+        ),
+
+    getCaption: function(spy)
+    {
+        return spy.method.toUpperCase() + " " + cropString(spy.getURL(), 100);
+    },
+
+    getFullUri: function(spy)
+    {
+        return spy.method.toUpperCase() + " " + spy.getURL();
+    },
+
+    getStatus: function(spy)
+    {
+        var text = "";
+        if (spy.statusCode)
+            text += spy.statusCode + " ";
+
+        if (spy.statusText)
+            return text += spy.statusText;
+
+        return text;
+    },
+
+    onToggleBody: function(event)
+    {
+        var target = event.currentTarget || event.srcElement;
+        var logRow = getAncestorByClass(target, "logRow-spy");
+
+        if (isLeftClick(event))
+        {
+            toggleClass(logRow, "opened");
+
+            var spy = getChildByClass(logRow, "spyHead").repObject;
+            var spyHeadTable = getAncestorByClass(target, "spyHeadTable");
+
+            if (hasClass(logRow, "opened"))
+            {
+                updateHttpSpyInfo(spy, logRow);
+                if (spyHeadTable)
+                    spyHeadTable.setAttribute('aria-expanded', 'true');
+            }
+            else
+            {
+                //var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody");
+                //dispatch(Firebug.NetMonitor.NetInfoBody.fbListeners, "destroyTabBody", [netInfoBox, spy]);
+                //if (spyHeadTable)
+                //    spyHeadTable.setAttribute('aria-expanded', 'false');
+            }
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    copyURL: function(spy)
+    {
+        copyToClipboard(spy.getURL());
+    },
+
+    copyParams: function(spy)
+    {
+        var text = spy.postText;
+        if (!text)
+            return;
+
+        var url = reEncodeURL(spy, text, true);
+        copyToClipboard(url);
+    },
+
+    copyResponse: function(spy)
+    {
+        copyToClipboard(spy.responseText);
+    },
+
+    openInTab: function(spy)
+    {
+        openNewTab(spy.getURL(), spy.postText);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    supportsObject: function(object)
+    {
+        // TODO: xxxpedro spy xhr
+        return false;
+
+        return object instanceof Firebug.Spy.XMLHttpRequestSpy;
+    },
+
+    browseObject: function(spy, context)
+    {
+        var url = spy.getURL();
+        openNewTab(url);
+        return true;
+    },
+
+    getRealObject: function(spy, context)
+    {
+        return spy.xhrRequest;
+    },
+
+    getContextMenuItems: function(spy)
+    {
+        var items = [
+            {label: "CopyLocation", command: bindFixed(this.copyURL, this, spy) }
+        ];
+
+        if (spy.postText)
+        {
+            items.push(
+                {label: "CopyLocationParameters", command: bindFixed(this.copyParams, this, spy) }
+            );
+        }
+
+        items.push(
+            {label: "CopyResponse", command: bindFixed(this.copyResponse, this, spy) },
+            "-",
+            {label: "OpenInTab", command: bindFixed(this.openInTab, this, spy) }
+        );
+
+        return items;
+    }
+});
+
+// ************************************************************************************************
+
+function updateTime(spy)
+{
+    var timeBox = spy.logRow.getElementsByClassName("spyTime").item(0);
+    if (spy.responseTime)
+        timeBox.textContent = " " + formatTime(spy.responseTime);
+}
+
+function updateLogRow(spy)
+{
+    updateTime(spy);
+
+    var statusBox = spy.logRow.getElementsByClassName("spyStatus").item(0);
+    statusBox.textContent = Firebug.Spy.XHR.getStatus(spy);
+
+    removeClass(spy.logRow, "loading");
+    setClass(spy.logRow, "loaded");
+
+    try
+    {
+        var errorRange = Math.floor(spy.xhrRequest.status/100);
+        if (errorRange == 4 || errorRange == 5)
+            setClass(spy.logRow, "error");
+    }
+    catch (exc)
+    {
+    }
+}
+
+var updateHttpSpyInfo = function updateHttpSpyInfo(spy, logRow)
+{
+    if (!spy.logRow && logRow)
+        spy.logRow = logRow;
+
+    if (!spy.logRow || !hasClass(spy.logRow, "opened"))
+        return;
+
+    if (!spy.params)
+        //spy.params = parseURLParams(spy.href+"");
+        spy.params = parseURLParams(spy.href+"");
+
+    if (!spy.requestHeaders)
+        spy.requestHeaders = getRequestHeaders(spy);
+
+    if (!spy.responseHeaders && spy.loaded)
+        spy.responseHeaders = getResponseHeaders(spy);
+
+    var template = Firebug.NetMonitor.NetInfoBody;
+    var netInfoBox = getChildByClass(spy.logRow, "spyHead", "netInfoBody");
+    if (!netInfoBox)
+    {
+        var head = getChildByClass(spy.logRow, "spyHead");
+        netInfoBox = template.tag.append({"file": spy}, head);
+        dispatch(template.fbListeners, "initTabBody", [netInfoBox, spy]);
+        template.selectTabByName(netInfoBox, "Response");
+    }
+    else
+    {
+        template.updateInfo(netInfoBox, spy, spy.context);
+    }
+};
+
+
+
+// ************************************************************************************************
+
+function getRequestHeaders(spy)
+{
+    var headers = [];
+
+    var channel = spy.xhrRequest.channel;
+    if (channel instanceof Ci.nsIHttpChannel)
+    {
+        channel.visitRequestHeaders({
+            visitHeader: function(name, value)
+            {
+                headers.push({name: name, value: value});
+            }
+        });
+    }
+
+    return headers;
+}
+
+function getResponseHeaders(spy)
+{
+    var headers = [];
+
+    try
+    {
+        var channel = spy.xhrRequest.channel;
+        if (channel instanceof Ci.nsIHttpChannel)
+        {
+            channel.visitResponseHeaders({
+                visitHeader: function(name, value)
+                {
+                    headers.push({name: name, value: value});
+                }
+            });
+        }
+    }
+    catch (exc)
+    {
+        if (FBTrace.DBG_SPY || FBTrace.DBG_ERRORS)
+            FBTrace.sysout("spy.getResponseHeaders; EXCEPTION " +
+                safeGetRequestName(spy.request), exc);
+    }
+
+    return headers;
+}
+
+// ************************************************************************************************
+// Registration
+
+Firebug.registerModule(Firebug.Spy);
+//Firebug.registerRep(Firebug.Spy.XHR);
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+
+// List of JSON content types.
+var contentTypes =
+{
+    // TODO: create issue: jsonViewer will not try to evaluate the contents of the requested file
+    // if the content-type is set to "text/plain"
+    //"text/plain": 1,
+    "text/javascript": 1,
+    "text/x-javascript": 1,
+    "text/json": 1,
+    "text/x-json": 1,
+    "application/json": 1,
+    "application/x-json": 1,
+    "application/javascript": 1,
+    "application/x-javascript": 1,
+    "application/json-rpc": 1
+};
+
+// ************************************************************************************************
+// Model implementation
+
+Firebug.JSONViewerModel = extend(Firebug.Module,
+{
+    dispatchName: "jsonViewer",
+    initialize: function()
+    {
+        Firebug.NetMonitor.NetInfoBody.addListener(this);
+
+        // Used by Firebug.DOMPanel.DirTable domplate.
+        this.toggles = {};
+    },
+
+    shutdown: function()
+    {
+        Firebug.NetMonitor.NetInfoBody.removeListener(this);
+    },
+
+    initTabBody: function(infoBox, file)
+    {
+        if (FBTrace.DBG_JSONVIEWER)
+            FBTrace.sysout("jsonviewer.initTabBody", infoBox);
+
+        // Let listeners to parse the JSON.
+        dispatch(this.fbListeners, "onParseJSON", [file]);
+
+        // The JSON is still no there, try to parse most common cases.
+        if (!file.jsonObject)
+        {
+            ///if (this.isJSON(safeGetContentType(file.request), file.responseText))
+            if (this.isJSON(file.mimeType, file.responseText))
+                file.jsonObject = this.parseJSON(file);
+        }
+
+        // The jsonObject is created so, the JSON tab can be displayed.
+        if (file.jsonObject && hasProperties(file.jsonObject))
+        {
+            Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "JSON",
+                ///$STR("jsonviewer.tab.JSON"));
+                $STR("JSON"));
+
+            if (FBTrace.DBG_JSONVIEWER)
+                FBTrace.sysout("jsonviewer.initTabBody; JSON object available " +
+                    (typeof(file.jsonObject) != "undefined"), file.jsonObject);
+        }
+    },
+
+    isJSON: function(contentType, data)
+    {
+        // Workaround for JSON responses without proper content type
+        // Let's consider all responses starting with "{" as JSON. In the worst
+        // case there will be an exception when parsing. This means that no-JSON
+        // responses (and post data) (with "{") can be parsed unnecessarily,
+        // which represents a little overhead, but this happens only if the request
+        // is actually expanded by the user in the UI (Net & Console panels).
+
+        ///var responseText = data ? trimLeft(data) : null;
+        ///if (responseText && responseText.indexOf("{") == 0)
+        ///    return true;
+        var responseText = data ? trim(data) : null;
+        if (responseText && responseText.indexOf("{") == 0)
+            return true;
+
+        if (!contentType)
+            return false;
+
+        contentType = contentType.split(";")[0];
+        contentType = trim(contentType);
+        return contentTypes[contentType];
+    },
+
+    // Update listener for TabView
+    updateTabBody: function(infoBox, file, context)
+    {
+        var tab = infoBox.selectedTab;
+        ///var tabBody = infoBox.getElementsByClassName("netInfoJSONText").item(0);
+        var tabBody = $$(".netInfoJSONText", infoBox)[0];
+        if (!hasClass(tab, "netInfoJSONTab") || tabBody.updated)
+            return;
+
+        tabBody.updated = true;
+
+        if (file.jsonObject) {
+            Firebug.DOMPanel.DirTable.tag.replace(
+                 {object: file.jsonObject, toggles: this.toggles}, tabBody);
+        }
+    },
+
+    parseJSON: function(file)
+    {
+        var jsonString = new String(file.responseText);
+        ///return parseJSONString(jsonString, "http://" + file.request.originalURI.host);
+        return parseJSONString(jsonString);
+    }
+});
+
+// ************************************************************************************************
+// Registration
+
+Firebug.registerModule(Firebug.JSONViewerModel);
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// Constants
+
+// List of XML related content types.
+var xmlContentTypes =
+[
+    "text/xml",
+    "application/xml",
+    "application/xhtml+xml",
+    "application/rss+xml",
+    "application/atom+xml",,
+    "application/vnd.mozilla.maybe.feed",
+    "application/rdf+xml",
+    "application/vnd.mozilla.xul+xml"
+];
+
+// ************************************************************************************************
+// Model implementation
+
+/**
+ * @module Implements viewer for XML based network responses. In order to create a new
+ * tab wihin network request detail, a listener is registered into
+ * <code>Firebug.NetMonitor.NetInfoBody</code> object.
+ */
+Firebug.XMLViewerModel = extend(Firebug.Module,
+{
+    dispatchName: "xmlViewer",
+
+    initialize: function()
+    {
+        ///Firebug.ActivableModule.initialize.apply(this, arguments);
+        Firebug.Module.initialize.apply(this, arguments);
+        Firebug.NetMonitor.NetInfoBody.addListener(this);
+    },
+
+    shutdown: function()
+    {
+        ///Firebug.ActivableModule.shutdown.apply(this, arguments);
+        Firebug.Module.shutdown.apply(this, arguments);
+        Firebug.NetMonitor.NetInfoBody.removeListener(this);
+    },
+
+    /**
+     * Check response's content-type and if it's a XML, create a new tab with XML preview.
+     */
+    initTabBody: function(infoBox, file)
+    {
+        if (FBTrace.DBG_XMLVIEWER)
+            FBTrace.sysout("xmlviewer.initTabBody", infoBox);
+
+        // If the response is XML let's display a pretty preview.
+        ///if (this.isXML(safeGetContentType(file.request)))
+        if (this.isXML(file.mimeType, file.responseText))
+        {
+            Firebug.NetMonitor.NetInfoBody.appendTab(infoBox, "XML",
+                ///$STR("xmlviewer.tab.XML"));
+                $STR("XML"));
+
+            if (FBTrace.DBG_XMLVIEWER)
+                FBTrace.sysout("xmlviewer.initTabBody; XML response available");
+        }
+    },
+
+    isXML: function(contentType)
+    {
+        if (!contentType)
+            return false;
+
+        // Look if the response is XML based.
+        for (var i=0; i<xmlContentTypes.length; i++)
+        {
+            if (contentType.indexOf(xmlContentTypes[i]) == 0)
+                return true;
+        }
+
+        return false;
+    },
+
+    /**
+     * Parse XML response and render pretty printed preview.
+     */
+    updateTabBody: function(infoBox, file, context)
+    {
+        var tab = infoBox.selectedTab;
+        ///var tabBody = infoBox.getElementsByClassName("netInfoXMLText").item(0);
+        var tabBody = $$(".netInfoXMLText", infoBox)[0];
+        if (!hasClass(tab, "netInfoXMLTab") || tabBody.updated)
+            return;
+
+        tabBody.updated = true;
+
+        this.insertXML(tabBody, Firebug.NetMonitor.Utils.getResponseText(file, context));
+    },
+
+    insertXML: function(parentNode, text)
+    {
+        var xmlText = text.replace(/^\s*<?.+?>\s*/, "");
+
+        var div = parentNode.ownerDocument.createElement("div");
+        div.innerHTML = xmlText;
+
+        var root = div.getElementsByTagName("*")[0];
+
+        /***
+        var parser = CCIN("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
+        var doc = parser.parseFromString(text, "text/xml");
+        var root = doc.documentElement;
+
+        // Error handling
+        var nsURI = "http://www.mozilla.org/newlayout/xml/parsererror.xml";
+        if (root.namespaceURI == nsURI && root.nodeName == "parsererror")
+        {
+            this.ParseError.tag.replace({error: {
+                message: root.firstChild.nodeValue,
+                source: root.lastChild.textContent
+            }}, parentNode);
+            return;
+        }
+        /**/
+
+        if (FBTrace.DBG_XMLVIEWER)
+            FBTrace.sysout("xmlviewer.updateTabBody; XML response parsed", doc);
+
+        // Override getHidden in these templates. The parsed XML documen is
+        // hidden, but we want to display it using 'visible' styling.
+        /*
+        var templates = [
+            Firebug.HTMLPanel.CompleteElement,
+            Firebug.HTMLPanel.Element,
+            Firebug.HTMLPanel.TextElement,
+            Firebug.HTMLPanel.EmptyElement,
+            Firebug.HTMLPanel.XEmptyElement,
+        ];
+
+        var originals = [];
+        for (var i=0; i<templates.length; i++)
+        {
+            originals[i] = templates[i].getHidden;
+            templates[i].getHidden = function() {
+                return "";
+            }
+        }
+        /**/
+
+        // Generate XML preview.
+        ///Firebug.HTMLPanel.CompleteElement.tag.replace({object: doc.documentElement}, parentNode);
+
+        // TODO: xxxpedro html3
+        ///Firebug.HTMLPanel.CompleteElement.tag.replace({object: root}, parentNode);
+        var html = [];
+        Firebug.Reps.appendNode(root, html);
+        parentNode.innerHTML = html.join("");
+
+
+        /*
+        for (var i=0; i<originals.length; i++)
+            templates[i].getHidden = originals[i];/**/
+    }
+});
+
+// ************************************************************************************************
+// Domplate
+
+/**
+ * @domplate Represents a template for displaying XML parser errors. Used by
+ * <code>Firebug.XMLViewerModel</code>.
+ */
+Firebug.XMLViewerModel.ParseError = domplate(Firebug.Rep,
+{
+    tag:
+        DIV({"class": "xmlInfoError"},
+            DIV({"class": "xmlInfoErrorMsg"}, "$error.message"),
+            PRE({"class": "xmlInfoErrorSource"}, "$error|getSource")
+        ),
+
+    getSource: function(error)
+    {
+        var parts = error.source.split("\n");
+        if (parts.length != 2)
+            return error.source;
+
+        var limit = 50;
+        var column = parts[1].length;
+        if (column >= limit) {
+            parts[0] = "..." + parts[0].substr(column - limit);
+            parts[1] = "..." + parts[1].substr(column - limit);
+        }
+
+        if (parts[0].length > 80)
+            parts[0] = parts[0].substr(0, 80) + "...";
+
+        return parts.join("\n");
+    }
+});
+
+// ************************************************************************************************
+// Registration
+
+Firebug.registerModule(Firebug.XMLViewerModel);
+
+}});
+
+
+/* See license.txt for terms of usage */
+
+// next-generation Console Panel (will override consoje.js)
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Constants
+
+/*
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const nsIPrefBranch2 = Ci.nsIPrefBranch2;
+const PrefService = Cc["@mozilla.org/preferences-service;1"];
+const prefs = PrefService.getService(nsIPrefBranch2);
+/**/
+/*
+
+// new offline message handler
+o = {x:1,y:2};
+
+r = Firebug.getRep(o);
+
+r.tag.tag.compile();
+
+outputs = [];
+html = r.tag.renderHTML({object:o}, outputs);
+
+
+// finish rendering the template (the DOM part)
+target = $("build");
+target.innerHTML = html;
+root = target.firstChild;
+
+domArgs = [root, r.tag.context, 0];
+domArgs.push.apply(domArgs, r.tag.domArgs);
+domArgs.push.apply(domArgs, outputs);
+r.tag.tag.renderDOM.apply(self ? self : r.tag.subject, domArgs);
+
+
+ */
+var consoleQueue = [];
+var lastHighlightedObject;
+var FirebugContext = Env.browser;
+
+// ************************************************************************************************
+
+var maxQueueRequests = 500;
+
+// ************************************************************************************************
+
+Firebug.ConsoleBase =
+{
+    log: function(object, context, className, rep, noThrottle, sourceLink)
+    {
+        //dispatch(this.fbListeners,"log",[context, object, className, sourceLink]);
+        return this.logRow(appendObject, object, context, className, rep, sourceLink, noThrottle);
+    },
+
+    logFormatted: function(objects, context, className, noThrottle, sourceLink)
+    {
+        //dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]);
+        return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle);
+    },
+
+    openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush)
+    {
+        return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle);
+    },
+
+    closeGroup: function(context, noThrottle)
+    {
+        return this.logRow(appendCloseGroup, null, context, null, null, null, noThrottle, true);
+    },
+
+    logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow)
+    {
+        // TODO: xxxpedro console console2
+        noThrottle = true; // xxxpedro forced because there is no TabContext yet
+
+        if (!context)
+            context = FirebugContext;
+
+        if (FBTrace.DBG_ERRORS && !context)
+            FBTrace.sysout("Console.logRow has no context, skipping objects", objects);
+
+        if (!context)
+            return;
+
+        if (noThrottle || !context)
+        {
+            var panel = this.getPanel(context);
+            if (panel)
+            {
+                var row = panel.append(appender, objects, className, rep, sourceLink, noRow);
+                var container = panel.panelNode;
+
+                // TODO: xxxpedro what is this? console console2
+                /*
+                var template = Firebug.NetMonitor.NetLimit;
+
+                while (container.childNodes.length > maxQueueRequests + 1)
+                {
+                    clearDomplate(container.firstChild.nextSibling);
+                    container.removeChild(container.firstChild.nextSibling);
+                    panel.limit.limitInfo.totalCount++;
+                    template.updateCounter(panel.limit);
+                }
+                dispatch([Firebug.A11yModel], "onLogRowCreated", [panel , row]);
+                /**/
+                return row;
+            }
+            else
+            {
+                consoleQueue.push([appender, objects, context, className, rep, sourceLink, noThrottle, noRow]);
+            }
+        }
+        else
+        {
+            if (!context.throttle)
+            {
+                //FBTrace.sysout("console.logRow has not context.throttle! ");
+                return;
+            }
+            var args = [appender, objects, context, className, rep, sourceLink, true, noRow];
+            context.throttle(this.logRow, this, args);
+        }
+    },
+
+    appendFormatted: function(args, row, context)
+    {
+        if (!context)
+            context = FirebugContext;
+
+        var panel = this.getPanel(context);
+        panel.appendFormatted(args, row);
+    },
+
+    clear: function(context)
+    {
+        if (!context)
+            //context = FirebugContext;
+            context = Firebug.context;
+
+        /*
+        if (context)
+            Firebug.Errors.clear(context);
+        /**/
+
+        var panel = this.getPanel(context, true);
+        if (panel)
+        {
+            panel.clear();
+        }
+    },
+
+    // Override to direct output to your panel
+    getPanel: function(context, noCreate)
+    {
+        //return context.getPanel("console", noCreate);
+        // TODO: xxxpedro console console2
+        return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null;
+    }
+
+};
+
+// ************************************************************************************************
+
+//TODO: xxxpedro
+//var ActivableConsole = extend(Firebug.ActivableModule, Firebug.ConsoleBase);
+var ActivableConsole = extend(Firebug.ConsoleBase,
+{
+    isAlwaysEnabled: function()
+    {
+        return true;
+    }
+});
+
+Firebug.Console = Firebug.Console = extend(ActivableConsole,
+//Firebug.Console = extend(ActivableConsole,
+{
+    dispatchName: "console",
+
+    error: function()
+    {
+        Firebug.Console.logFormatted(arguments, Firebug.browser, "error");
+    },
+
+    flush: function()
+    {
+        dispatch(this.fbListeners,"flush",[]);
+
+        for (var i=0, length=consoleQueue.length; i<length; i++)
+        {
+            var args = consoleQueue[i];
+            this.logRow.apply(this, args);
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Module
+
+    showPanel: function(browser, panel)
+    {
+    },
+
+    getFirebugConsoleElement: function(context, win)
+    {
+        var element = win.document.getElementById("_firebugConsole");
+        if (!element)
+        {
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("getFirebugConsoleElement forcing element");
+            var elementForcer = "(function(){var r=null; try { r = window._getFirebugConsoleElement();}catch(exc){r=exc;} return r;})();";  // we could just add the elements here
+
+            if (context.stopped)
+                Firebug.Console.injector.evaluateConsoleScript(context);  // todo evaluate consoleForcer on stack
+            else
+                var r = Firebug.CommandLine.evaluateInWebPage(elementForcer, context, win);
+
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("getFirebugConsoleElement forcing element result "+r, r);
+
+            var element = win.document.getElementById("_firebugConsole");
+            if (!element) // elementForce fails
+            {
+                if (FBTrace.DBG_ERRORS) FBTrace.sysout("console.getFirebugConsoleElement: no _firebugConsole in win:", win);
+                Firebug.Console.logFormatted(["Firebug cannot find _firebugConsole element", r, win], context, "error", true);
+            }
+        }
+
+        return element;
+    },
+
+    isReadyElsePreparing: function(context, win) // this is the only code that should call injector.attachIfNeeded
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.isReadyElsePreparing, win is " +
+                (win?"an argument: ":"null, context.window: ") +
+                (win?win.location:context.window.location), (win?win:context.window));
+
+        if (win)
+            return this.injector.attachIfNeeded(context, win);
+        else
+        {
+            var attached = true;
+            for (var i = 0; i < context.windows.length; i++)
+                attached = attached && this.injector.attachIfNeeded(context, context.windows[i]);
+            // already in the list above attached = attached && this.injector.attachIfNeeded(context, context.window);
+            if (context.windows.indexOf(context.window) == -1)
+                FBTrace.sysout("isReadyElsePreparing ***************** context.window not in context.windows");
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("console.isReadyElsePreparing attached to "+context.windows.length+" and returns "+attached);
+            return attached;
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends ActivableModule
+
+    initialize: function()
+    {
+        this.panelName = "console";
+
+        //TODO: xxxpedro
+        //Firebug.ActivableModule.initialize.apply(this, arguments);
+        //Firebug.Debugger.addListener(this);
+    },
+
+    enable: function()
+    {
+        if (Firebug.Console.isAlwaysEnabled())
+            this.watchForErrors();
+    },
+
+    disable: function()
+    {
+        if (Firebug.Console.isAlwaysEnabled())
+            this.unwatchForErrors();
+    },
+
+    initContext: function(context, persistedState)
+    {
+        Firebug.ActivableModule.initContext.apply(this, arguments);
+        context.consoleReloadWarning = true;  // mark as need to warn.
+    },
+
+    loadedContext: function(context)
+    {
+        for (var url in context.sourceFileMap)
+            return;  // if there are any sourceFiles, then do nothing
+
+        // else we saw no JS, so the reload warning it not needed.
+        this.clearReloadWarning(context);
+    },
+
+    clearReloadWarning: function(context) // remove the warning about reloading.
+    {
+         if (context.consoleReloadWarning)
+         {
+             var panel = context.getPanel(this.panelName);
+             panel.clearReloadWarning();
+             delete context.consoleReloadWarning;
+         }
+    },
+
+    togglePersist: function(context)
+    {
+        var panel = context.getPanel(this.panelName);
+        panel.persistContent = panel.persistContent ? false : true;
+        Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", panel.persistContent);
+    },
+
+    showContext: function(browser, context)
+    {
+        Firebug.chrome.setGlobalAttribute("cmd_clearConsole", "disabled", !context);
+
+        Firebug.ActivableModule.showContext.apply(this, arguments);
+    },
+
+    destroyContext: function(context, persistedState)
+    {
+        Firebug.Console.injector.detachConsole(context, context.window);  // TODO iterate windows?
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onPanelEnable: function(panelName)
+    {
+        if (panelName != this.panelName)  // we don't care about other panels
+            return;
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.onPanelEnable**************");
+
+        this.watchForErrors();
+        Firebug.Debugger.addDependentModule(this); // we inject the console during JS compiles so we need jsd
+    },
+
+    onPanelDisable: function(panelName)
+    {
+        if (panelName != this.panelName)  // we don't care about other panels
+            return;
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.onPanelDisable**************");
+
+        Firebug.Debugger.removeDependentModule(this); // we inject the console during JS compiles so we need jsd
+        this.unwatchForErrors();
+
+        // Make sure possible errors coming from the page and displayed in the Firefox
+        // status bar are removed.
+        this.clear();
+    },
+
+    onSuspendFirebug: function()
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.onSuspendFirebug\n");
+        if (Firebug.Console.isAlwaysEnabled())
+            this.unwatchForErrors();
+    },
+
+    onResumeFirebug: function()
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.onResumeFirebug\n");
+        if (Firebug.Console.isAlwaysEnabled())
+            this.watchForErrors();
+    },
+
+    watchForErrors: function()
+    {
+        Firebug.Errors.checkEnabled();
+        $('fbStatusIcon').setAttribute("console", "on");
+    },
+
+    unwatchForErrors: function()
+    {
+        Firebug.Errors.checkEnabled();
+        $('fbStatusIcon').removeAttribute("console");
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Firebug.Debugger listener
+
+    onMonitorScript: function(context, frame)
+    {
+        Firebug.Console.log(frame, context);
+    },
+
+    onFunctionCall: function(context, frame, depth, calling)
+    {
+        if (calling)
+            Firebug.Console.openGroup([frame, "depth:"+depth], context);
+        else
+            Firebug.Console.closeGroup(context);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    logRow: function(appender, objects, context, className, rep, sourceLink, noThrottle, noRow)
+    {
+        if (!context)
+            context = FirebugContext;
+
+        if (FBTrace.DBG_WINDOWS && !context) FBTrace.sysout("Console.logRow: no context \n");
+
+        if (this.isAlwaysEnabled())
+            return Firebug.ConsoleBase.logRow.apply(this, arguments);
+    }
+});
+
+Firebug.ConsoleListener =
+{
+    log: function(context, object, className, sourceLink)
+    {
+    },
+
+    logFormatted: function(context, objects, className, sourceLink)
+    {
+    }
+};
+
+// ************************************************************************************************
+
+Firebug.ConsolePanel = function () {} // XXjjb attach Firebug so this panel can be extended.
+
+//TODO: xxxpedro
+//Firebug.ConsolePanel.prototype = extend(Firebug.ActivablePanel,
+Firebug.ConsolePanel.prototype = extend(Firebug.Panel,
+{
+    wasScrolledToBottom: false,
+    messageCount: 0,
+    lastLogTime: 0,
+    groups: null,
+    limit: null,
+
+    append: function(appender, objects, className, rep, sourceLink, noRow)
+    {
+        var container = this.getTopContainer();
+
+        if (noRow)
+        {
+            appender.apply(this, [objects]);
+        }
+        else
+        {
+            // xxxHonza: Don't update the this.wasScrolledToBottom flag now.
+            // At the beginning (when the first log is created) the isScrolledToBottom
+            // always returns true.
+            //if (this.panelNode.offsetHeight)
+            //    this.wasScrolledToBottom = isScrolledToBottom(this.panelNode);
+
+            var row = this.createRow("logRow", className);
+            appender.apply(this, [objects, row, rep]);
+
+            if (sourceLink)
+                FirebugReps.SourceLink.tag.append({object: sourceLink}, row);
+
+            container.appendChild(row);
+
+            this.filterLogRow(row, this.wasScrolledToBottom);
+
+            if (this.wasScrolledToBottom)
+                scrollToBottom(this.panelNode);
+
+            return row;
+        }
+    },
+
+    clear: function()
+    {
+        if (this.panelNode)
+        {
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("ConsolePanel.clear");
+            clearNode(this.panelNode);
+            this.insertLogLimit(this.context);
+        }
+    },
+
+    insertLogLimit: function()
+    {
+        // Create limit row. This row is the first in the list of entries
+        // and initially hidden. It's displayed as soon as the number of
+        // entries reaches the limit.
+        var row = this.createRow("limitRow");
+
+        var limitInfo = {
+            totalCount: 0,
+            limitPrefsTitle: $STRF("LimitPrefsTitle", [Firebug.prefDomain+".console.logLimit"])
+        };
+
+        //TODO: xxxpedro console net limit!?
+        return;
+        var netLimitRep = Firebug.NetMonitor.NetLimit;
+        var nodes = netLimitRep.createTable(row, limitInfo);
+
+        this.limit = nodes[1];
+
+        var container = this.panelNode;
+        container.insertBefore(nodes[0], container.firstChild);
+    },
+
+    insertReloadWarning: function()
+    {
+        // put the message in, we will clear if the window console is injected.
+        this.warningRow = this.append(appendObject, $STR("message.Reload to activate window console"), "info");
+    },
+
+    clearReloadWarning: function()
+    {
+        if (this.warningRow)
+        {
+            this.warningRow.parentNode.removeChild(this.warningRow);
+            delete this.warningRow;
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    appendObject: function(object, row, rep)
+    {
+        if (!rep)
+            rep = Firebug.getRep(object);
+        return rep.tag.append({object: object}, row);
+    },
+
+    appendFormatted: function(objects, row, rep)
+    {
+        if (!objects || !objects.length)
+            return;
+
+        function logText(text, row)
+        {
+            var node = row.ownerDocument.createTextNode(text);
+            row.appendChild(node);
+        }
+
+        var format = objects[0];
+        var objIndex = 0;
+
+        if (typeof(format) != "string")
+        {
+            format = "";
+            objIndex = -1;
+        }
+        else  // a string
+        {
+            if (objects.length === 1) // then we have only a string...
+            {
+                if (format.length < 1) { // ...and it has no characters.
+                    logText("(an empty string)", row);
+                    return;
+                }
+            }
+        }
+
+        var parts = parseFormat(format);
+        var trialIndex = objIndex;
+        for (var i= 0; i < parts.length; i++)
+        {
+            var part = parts[i];
+            if (part && typeof(part) == "object")
+            {
+                if (++trialIndex > objects.length)  // then too few parameters for format, assume unformatted.
+                {
+                    format = "";
+                    objIndex = -1;
+                    parts.length = 0;
+                    break;
+                }
+            }
+
+        }
+        for (var i = 0; i < parts.length; ++i)
+        {
+            var part = parts[i];
+            if (part && typeof(part) == "object")
+            {
+                var object = objects[++objIndex];
+                if (typeof(object) != "undefined")
+                    this.appendObject(object, row, part.rep);
+                else
+                    this.appendObject(part.type, row, FirebugReps.Text);
+            }
+            else
+                FirebugReps.Text.tag.append({object: part}, row);
+        }
+
+        for (var i = objIndex+1; i < objects.length; ++i)
+        {
+            logText(" ", row);
+            var object = objects[i];
+            if (typeof(object) == "string")
+                FirebugReps.Text.tag.append({object: object}, row);
+            else
+                this.appendObject(object, row);
+        }
+    },
+
+    appendOpenGroup: function(objects, row, rep)
+    {
+        if (!this.groups)
+            this.groups = [];
+
+        setClass(row, "logGroup");
+        setClass(row, "opened");
+
+        var innerRow = this.createRow("logRow");
+        setClass(innerRow, "logGroupLabel");
+        if (rep)
+            rep.tag.replace({"objects": objects}, innerRow);
+        else
+            this.appendFormatted(objects, innerRow, rep);
+        row.appendChild(innerRow);
+        //dispatch([Firebug.A11yModel], 'onLogRowCreated', [this, innerRow]);
+        var groupBody = this.createRow("logGroupBody");
+        row.appendChild(groupBody);
+        groupBody.setAttribute('role', 'group');
+        this.groups.push(groupBody);
+
+        addEvent(innerRow, "mousedown", function(event)
+        {
+            if (isLeftClick(event))
+            {
+                //console.log(event.currentTarget == event.target);
+
+                var target = event.target || event.srcElement;
+
+                target = getAncestorByClass(target, "logGroupLabel");
+
+                var groupRow = target.parentNode;
+
+                if (hasClass(groupRow, "opened"))
+                {
+                    removeClass(groupRow, "opened");
+                    target.setAttribute('aria-expanded', 'false');
+                }
+                else
+                {
+                    setClass(groupRow, "opened");
+                    target.setAttribute('aria-expanded', 'true');
+                }
+            }
+        });
+    },
+
+    appendCloseGroup: function(object, row, rep)
+    {
+        if (this.groups)
+            this.groups.pop();
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // TODO: xxxpedro console2
+    onMouseMove: function(event)
+    {
+        if (!Firebug.Inspector) return;
+
+        var target = event.srcElement || event.target;
+
+        var object = getAncestorByClass(target, "objectLink-element");
+        object = object ? object.repObject : null;
+
+        if(object && instanceOf(object, "Element") && object.nodeType == 1)
+        {
+            if(object != lastHighlightedObject)
+            {
+                Firebug.Inspector.drawBoxModel(object);
+                object = lastHighlightedObject;
+            }
+        }
+        else
+            Firebug.Inspector.hideBoxModel();
+
+    },
+
+    onMouseDown: function(event)
+    {
+        var target = event.srcElement || event.target;
+
+        var object = getAncestorByClass(target, "objectLink");
+        var repObject = object ? object.repObject : null;
+
+        if (!repObject)
+        {
+            return;
+        }
+
+        if (hasClass(object, "objectLink-object"))
+        {
+            Firebug.chrome.selectPanel("DOM");
+            Firebug.chrome.getPanel("DOM").select(repObject, true);
+        }
+        else if (hasClass(object, "objectLink-element"))
+        {
+            Firebug.chrome.selectPanel("HTML");
+            Firebug.chrome.getPanel("HTML").select(repObject, true);
+        }
+
+        /*
+        if(object && instanceOf(object, "Element") && object.nodeType == 1)
+        {
+            if(object != lastHighlightedObject)
+            {
+                Firebug.Inspector.drawBoxModel(object);
+                object = lastHighlightedObject;
+            }
+        }
+        else
+            Firebug.Inspector.hideBoxModel();
+        /**/
+
+    },
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    name: "Console",
+    title: "Console",
+    //searchable: true,
+    //breakable: true,
+    //editable: false,
+
+    options:
+    {
+        hasCommandLine: true,
+        hasToolButtons: true,
+        isPreRendered: true
+    },
+
+    create: function()
+    {
+        Firebug.Panel.create.apply(this, arguments);
+
+        this.context = Firebug.browser.window;
+        this.document = Firebug.chrome.document;
+        this.onMouseMove = bind(this.onMouseMove, this);
+        this.onMouseDown = bind(this.onMouseDown, this);
+
+        this.clearButton = new Button({
+            element: $("fbConsole_btClear"),
+            owner: Firebug.Console,
+            onClick: Firebug.Console.clear
+        });
+    },
+
+    initialize: function()
+    {
+        Firebug.Panel.initialize.apply(this, arguments);  // loads persisted content
+        //Firebug.ActivablePanel.initialize.apply(this, arguments);  // loads persisted content
+
+        if (!this.persistedContent && Firebug.Console.isAlwaysEnabled())
+        {
+            this.insertLogLimit(this.context);
+
+            // Initialize log limit and listen for changes.
+            this.updateMaxLimit();
+
+            if (this.context.consoleReloadWarning)  // we have not yet injected the console
+                this.insertReloadWarning();
+        }
+
+        //Firebug.Console.injector.install(Firebug.browser.window);
+
+        addEvent(this.panelNode, "mouseover", this.onMouseMove);
+        addEvent(this.panelNode, "mousedown", this.onMouseDown);
+
+        this.clearButton.initialize();
+
+        //consolex.trace();
+        //TODO: xxxpedro remove this
+        /*
+        Firebug.Console.openGroup(["asd"], null, "group", null, false);
+        Firebug.Console.log("asd");
+        Firebug.Console.log("asd");
+        Firebug.Console.log("asd");
+        /**/
+
+        //TODO: xxxpedro preferences prefs
+        //prefs.addObserver(Firebug.prefDomain, this, false);
+    },
+
+    initializeNode : function()
+    {
+        //dispatch([Firebug.A11yModel], 'onInitializeNode', [this]);
+        if (FBTrace.DBG_CONSOLE)
+        {
+            this.onScroller = bind(this.onScroll, this);
+            addEvent(this.panelNode, "scroll", this.onScroller);
+        }
+
+        this.onResizer = bind(this.onResize, this);
+        this.resizeEventTarget = Firebug.chrome.$('fbContentBox');
+        addEvent(this.resizeEventTarget, "resize", this.onResizer);
+    },
+
+    destroyNode : function()
+    {
+        //dispatch([Firebug.A11yModel], 'onDestroyNode', [this]);
+        if (this.onScroller)
+            removeEvent(this.panelNode, "scroll", this.onScroller);
+
+        //removeEvent(this.resizeEventTarget, "resize", this.onResizer);
+    },
+
+    shutdown: function()
+    {
+        //TODO: xxxpedro console console2
+        this.clearButton.shutdown();
+
+        removeEvent(this.panelNode, "mousemove", this.onMouseMove);
+        removeEvent(this.panelNode, "mousedown", this.onMouseDown);
+
+        this.destroyNode();
+
+        Firebug.Panel.shutdown.apply(this, arguments);
+
+        //TODO: xxxpedro preferences prefs
+        //prefs.removeObserver(Firebug.prefDomain, this, false);
+    },
+
+    ishow: function(state)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("Console.panel show; " + this.context.getName(), state);
+
+        var enabled = Firebug.Console.isAlwaysEnabled();
+        if (enabled)
+        {
+             Firebug.Console.disabledPanelPage.hide(this);
+             this.showCommandLine(true);
+             this.showToolbarButtons("fbConsoleButtons", true);
+             Firebug.chrome.setGlobalAttribute("cmd_togglePersistConsole", "checked", this.persistContent);
+
+             if (state && state.wasScrolledToBottom)
+             {
+                 this.wasScrolledToBottom = state.wasScrolledToBottom;
+                 delete state.wasScrolledToBottom;
+             }
+
+             if (this.wasScrolledToBottom)
+                 scrollToBottom(this.panelNode);
+
+             if (FBTrace.DBG_CONSOLE)
+                 FBTrace.sysout("console.show ------------------ wasScrolledToBottom: " +
+                    this.wasScrolledToBottom + ", " + this.context.getName());
+        }
+        else
+        {
+            this.hide(state);
+            Firebug.Console.disabledPanelPage.show(this);
+        }
+    },
+
+    ihide: function(state)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("Console.panel hide; " + this.context.getName(), state);
+
+        this.showToolbarButtons("fbConsoleButtons", false);
+        this.showCommandLine(false);
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.hide ------------------ wasScrolledToBottom: " +
+                this.wasScrolledToBottom + ", " + this.context.getName());
+    },
+
+    destroy: function(state)
+    {
+        if (this.panelNode.offsetHeight)
+            this.wasScrolledToBottom = isScrolledToBottom(this.panelNode);
+
+        if (state)
+            state.wasScrolledToBottom = this.wasScrolledToBottom;
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.destroy ------------------ wasScrolledToBottom: " +
+                this.wasScrolledToBottom + ", " + this.context.getName());
+    },
+
+    shouldBreakOnNext: function()
+    {
+        // xxxHonza: shouldn't the breakOnErrors be context related?
+        // xxxJJB, yes, but we can't support it because we can't yet tell
+        // which window the error is on.
+        return Firebug.getPref(Firebug.servicePrefDomain, "breakOnErrors");
+    },
+
+    getBreakOnNextTooltip: function(enabled)
+    {
+        return (enabled ? $STR("console.Disable Break On All Errors") :
+            $STR("console.Break On All Errors"));
+    },
+
+    enablePanel: function(module)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.ConsolePanel.enablePanel; " + this.context.getName());
+
+        Firebug.ActivablePanel.enablePanel.apply(this, arguments);
+
+        this.showCommandLine(true);
+
+        if (this.wasScrolledToBottom)
+            scrollToBottom(this.panelNode);
+    },
+
+    disablePanel: function(module)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.ConsolePanel.disablePanel; " + this.context.getName());
+
+        Firebug.ActivablePanel.disablePanel.apply(this, arguments);
+
+        this.showCommandLine(false);
+    },
+
+    getOptionsMenuItems: function()
+    {
+        return [
+            optionMenu("ShowJavaScriptErrors", "showJSErrors"),
+            optionMenu("ShowJavaScriptWarnings", "showJSWarnings"),
+            optionMenu("ShowCSSErrors", "showCSSErrors"),
+            optionMenu("ShowXMLErrors", "showXMLErrors"),
+            optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests"),
+            optionMenu("ShowChromeErrors", "showChromeErrors"),
+            optionMenu("ShowChromeMessages", "showChromeMessages"),
+            optionMenu("ShowExternalErrors", "showExternalErrors"),
+            optionMenu("ShowNetworkErrors", "showNetworkErrors"),
+            this.getShowStackTraceMenuItem(),
+            this.getStrictOptionMenuItem(),
+            "-",
+            optionMenu("LargeCommandLine", "largeCommandLine")
+        ];
+    },
+
+    getShowStackTraceMenuItem: function()
+    {
+        var menuItem = serviceOptionMenu("ShowStackTrace", "showStackTrace");
+        if (FirebugContext && !Firebug.Debugger.isAlwaysEnabled())
+            menuItem.disabled = true;
+        return menuItem;
+    },
+
+    getStrictOptionMenuItem: function()
+    {
+        var strictDomain = "javascript.options";
+        var strictName = "strict";
+        var strictValue = prefs.getBoolPref(strictDomain+"."+strictName);
+        return {label: "JavascriptOptionsStrict", type: "checkbox", checked: strictValue,
+            command: bindFixed(Firebug.setPref, Firebug, strictDomain, strictName, !strictValue) };
+    },
+
+    getBreakOnMenuItems: function()
+    {
+        //xxxHonza: no BON options for now.
+        /*return [
+            optionMenu("console.option.Persist Break On Error", "persistBreakOnError")
+        ];*/
+       return [];
+    },
+
+    search: function(text)
+    {
+        if (!text)
+            return;
+
+        // Make previously visible nodes invisible again
+        if (this.matchSet)
+        {
+            for (var i in this.matchSet)
+                removeClass(this.matchSet[i], "matched");
+        }
+
+        this.matchSet = [];
+
+        function findRow(node) { return getAncestorByClass(node, "logRow"); }
+        var search = new TextSearch(this.panelNode, findRow);
+
+        var logRow = search.find(text);
+        if (!logRow)
+        {
+            dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, []]);
+            return false;
+        }
+        for (; logRow; logRow = search.findNext())
+        {
+            setClass(logRow, "matched");
+            this.matchSet.push(logRow);
+        }
+        dispatch([Firebug.A11yModel], 'onConsoleSearchMatchFound', [this, text, this.matchSet]);
+        return true;
+    },
+
+    breakOnNext: function(breaking)
+    {
+        Firebug.setPref(Firebug.servicePrefDomain, "breakOnErrors", breaking);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // private
+
+    createRow: function(rowName, className)
+    {
+        var elt = this.document.createElement("div");
+        elt.className = rowName + (className ? " " + rowName + "-" + className : "");
+        return elt;
+    },
+
+    getTopContainer: function()
+    {
+        if (this.groups && this.groups.length)
+            return this.groups[this.groups.length-1];
+        else
+            return this.panelNode;
+    },
+
+    filterLogRow: function(logRow, scrolledToBottom)
+    {
+        if (this.searchText)
+        {
+            setClass(logRow, "matching");
+            setClass(logRow, "matched");
+
+            // Search after a delay because we must wait for a frame to be created for
+            // the new logRow so that the finder will be able to locate it
+            setTimeout(bindFixed(function()
+            {
+                if (this.searchFilter(this.searchText, logRow))
+                    this.matchSet.push(logRow);
+                else
+                    removeClass(logRow, "matched");
+
+                removeClass(logRow, "matching");
+
+                if (scrolledToBottom)
+                    scrollToBottom(this.panelNode);
+            }, this), 100);
+        }
+    },
+
+    searchFilter: function(text, logRow)
+    {
+        var count = this.panelNode.childNodes.length;
+        var searchRange = this.document.createRange();
+        searchRange.setStart(this.panelNode, 0);
+        searchRange.setEnd(this.panelNode, count);
+
+        var startPt = this.document.createRange();
+        startPt.setStartBefore(logRow);
+
+        var endPt = this.document.createRange();
+        endPt.setStartAfter(logRow);
+
+        return finder.Find(text, searchRange, startPt, endPt) != null;
+    },
+
+    // nsIPrefObserver
+    observe: function(subject, topic, data)
+    {
+        // We're observing preferences only.
+        if (topic != "nsPref:changed")
+          return;
+
+        // xxxHonza check this out.
+        var prefDomain = "Firebug.extension.";
+        var prefName = data.substr(prefDomain.length);
+        if (prefName == "console.logLimit")
+            this.updateMaxLimit();
+    },
+
+    updateMaxLimit: function()
+    {
+        var value = 1000;
+        //TODO: xxxpedro preferences log limit?
+        //var value = Firebug.getPref(Firebug.prefDomain, "console.logLimit");
+        maxQueueRequests =  value ? value : maxQueueRequests;
+    },
+
+    showCommandLine: function(shouldShow)
+    {
+        //TODO: xxxpedro show command line important
+        return;
+
+        if (shouldShow)
+        {
+            collapse(Firebug.chrome.$("fbCommandBox"), false);
+            Firebug.CommandLine.setMultiLine(Firebug.largeCommandLine, Firebug.chrome);
+        }
+        else
+        {
+            // Make sure that entire content of the Console panel is hidden when
+            // the panel is disabled.
+            Firebug.CommandLine.setMultiLine(false, Firebug.chrome, Firebug.largeCommandLine);
+            collapse(Firebug.chrome.$("fbCommandBox"), true);
+        }
+    },
+
+    onScroll: function(event)
+    {
+        // Update the scroll position flag if the position changes.
+        this.wasScrolledToBottom = FBL.isScrolledToBottom(this.panelNode);
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.onScroll ------------------ wasScrolledToBottom: " +
+                this.wasScrolledToBottom + ", wasScrolledToBottom: " +
+                this.context.getName(), event);
+    },
+
+    onResize: function(event)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("console.onResize ------------------ wasScrolledToBottom: " +
+                this.wasScrolledToBottom + ", offsetHeight: " + this.panelNode.offsetHeight +
+                ", scrollTop: " + this.panelNode.scrollTop + ", scrollHeight: " +
+                this.panelNode.scrollHeight + ", " + this.context.getName(), event);
+
+        if (this.wasScrolledToBottom)
+            scrollToBottom(this.panelNode);
+    }
+});
+
+// ************************************************************************************************
+
+function parseFormat(format)
+{
+    var parts = [];
+    if (format.length <= 0)
+        return parts;
+
+    var reg = /((^%|.%)(\d+)?(\.)([a-zA-Z]))|((^%|.%)([a-zA-Z]))/;
+    for (var m = reg.exec(format); m; m = reg.exec(format))
+    {
+        if (m[0].substr(0, 2) == "%%")
+        {
+            parts.push(format.substr(0, m.index));
+            parts.push(m[0].substr(1));
+        }
+        else
+        {
+            var type = m[8] ? m[8] : m[5];
+            var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);
+
+            var rep = null;
+            switch (type)
+            {
+                case "s":
+                    rep = FirebugReps.Text;
+                    break;
+                case "f":
+                case "i":
+                case "d":
+                    rep = FirebugReps.Number;
+                    break;
+                case "o":
+                    rep = null;
+                    break;
+            }
+
+            parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
+            parts.push({rep: rep, precision: precision, type: ("%" + type)});
+        }
+
+        format = format.substr(m.index+m[0].length);
+    }
+
+    parts.push(format);
+    return parts;
+}
+
+// ************************************************************************************************
+
+var appendObject = Firebug.ConsolePanel.prototype.appendObject;
+var appendFormatted = Firebug.ConsolePanel.prototype.appendFormatted;
+var appendOpenGroup = Firebug.ConsolePanel.prototype.appendOpenGroup;
+var appendCloseGroup = Firebug.ConsolePanel.prototype.appendCloseGroup;
+
+// ************************************************************************************************
+
+//Firebug.registerActivableModule(Firebug.Console);
+Firebug.registerModule(Firebug.Console);
+Firebug.registerPanel(Firebug.ConsolePanel);
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// Constants
+
+//const Cc = Components.classes;
+//const Ci = Components.interfaces;
+
+var frameCounters = {};
+var traceRecursion = 0;
+
+Firebug.Console.injector =
+{
+    install: function(context)
+    {
+        var win = context.window;
+
+        var consoleHandler = new FirebugConsoleHandler(context, win);
+
+        var properties =
+        [
+            "log",
+            "debug",
+            "info",
+            "warn",
+            "error",
+            "assert",
+            "dir",
+            "dirxml",
+            "group",
+            "groupCollapsed",
+            "groupEnd",
+            "time",
+            "timeEnd",
+            "count",
+            "trace",
+            "profile",
+            "profileEnd",
+            "clear",
+            "open",
+            "close"
+        ];
+
+        var Handler = function(name)
+        {
+            var c = consoleHandler;
+            var f = consoleHandler[name];
+            return function(){return f.apply(c,arguments);};
+        };
+
+        var installer = function(c)
+        {
+            for (var i=0, l=properties.length; i<l; i++)
+            {
+                var name = properties[i];
+                c[name] = new Handler(name);
+                c.firebuglite = Firebug.version;
+            }
+        };
+
+        var sandbox;
+
+        if (win.console)
+        {
+            if (Env.Options.overrideConsole)
+                sandbox = new win.Function("arguments.callee.install(window.console={})");
+            else
+                // if there's a console object and overrideConsole is false we should just quit
+                return;
+        }
+        else
+        {
+            try
+            {
+                // try overriding the console object
+                sandbox = new win.Function("arguments.callee.install(window.console={})");
+            }
+            catch(E)
+            {
+                // if something goes wrong create the firebug object instead
+                sandbox = new win.Function("arguments.callee.install(window.firebug={})");
+            }
+        }
+
+        sandbox.install = installer;
+        sandbox();
+    },
+
+    isAttached: function(context, win)
+    {
+        if (win.wrappedJSObject)
+        {
+            var attached = (win.wrappedJSObject._getFirebugConsoleElement ? true : false);
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("Console.isAttached:"+attached+" to win.wrappedJSObject "+safeGetWindowLocation(win.wrappedJSObject));
+
+            return attached;
+        }
+        else
+        {
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("Console.isAttached? to win "+win.location+" fnc:"+win._getFirebugConsoleElement);
+            return (win._getFirebugConsoleElement ? true : false);
+        }
+    },
+
+    attachIfNeeded: function(context, win)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("Console.attachIfNeeded has win "+(win? ((win.wrappedJSObject?"YES":"NO")+" wrappedJSObject"):"null") );
+
+        if (this.isAttached(context, win))
+            return true;
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("Console.attachIfNeeded found isAttached false ");
+
+        this.attachConsoleInjector(context, win);
+        this.addConsoleListener(context, win);
+
+        Firebug.Console.clearReloadWarning(context);
+
+        var attached =  this.isAttached(context, win);
+        if (attached)
+            dispatch(Firebug.Console.fbListeners, "onConsoleInjected", [context, win]);
+
+        return attached;
+    },
+
+    attachConsoleInjector: function(context, win)
+    {
+        var consoleInjection = this.getConsoleInjectionScript();  // Do it all here.
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("attachConsoleInjector evaluating in "+win.location, consoleInjection);
+
+        Firebug.CommandLine.evaluateInWebPage(consoleInjection, context, win);
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("attachConsoleInjector evaluation completed for "+win.location);
+    },
+
+    getConsoleInjectionScript: function() {
+        if (!this.consoleInjectionScript)
+        {
+            var script = "";
+            script += "window.__defineGetter__('console', function() {\n";
+            script += " return (window._firebug ? window._firebug : window.loadFirebugConsole()); })\n\n";
+
+            script += "window.loadFirebugConsole = function() {\n";
+            script += "window._firebug =  new _FirebugConsole();";
+
+            if (FBTrace.DBG_CONSOLE)
+                script += " window.dump('loadFirebugConsole '+window.location+'\\n');\n";
+
+            script += " return window._firebug };\n";
+
+            var theFirebugConsoleScript = getResource("chrome://firebug/content/consoleInjected.js");
+            script += theFirebugConsoleScript;
+
+
+            this.consoleInjectionScript = script;
+        }
+        return this.consoleInjectionScript;
+    },
+
+    forceConsoleCompilationInPage: function(context, win)
+    {
+        if (!win)
+        {
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("no win in forceConsoleCompilationInPage!");
+            return;
+        }
+
+        var consoleForcer = "window.loadFirebugConsole();";
+
+        if (context.stopped)
+            Firebug.Console.injector.evaluateConsoleScript(context);  // todo evaluate consoleForcer on stack
+        else
+            Firebug.CommandLine.evaluateInWebPage(consoleForcer, context, win);
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("forceConsoleCompilationInPage "+win.location, consoleForcer);
+    },
+
+    evaluateConsoleScript: function(context)
+    {
+        var scriptSource = this.getConsoleInjectionScript(); // TODO XXXjjb this should be getConsoleInjectionScript
+        Firebug.Debugger.evaluate(scriptSource, context);
+    },
+
+    addConsoleListener: function(context, win)
+    {
+        if (!context.activeConsoleHandlers)  // then we have not been this way before
+            context.activeConsoleHandlers = [];
+        else
+        {   // we've been this way before...
+            for (var i=0; i<context.activeConsoleHandlers.length; i++)
+            {
+                if (context.activeConsoleHandlers[i].window == win)
+                {
+                    context.activeConsoleHandlers[i].detach();
+                    if (FBTrace.DBG_CONSOLE)
+                        FBTrace.sysout("consoleInjector addConsoleListener removed handler("+context.activeConsoleHandlers[i].handler_name+") from _firebugConsole in : "+win.location+"\n");
+                    context.activeConsoleHandlers.splice(i,1);
+                }
+            }
+        }
+
+        // We need the element to attach our event listener.
+        var element = Firebug.Console.getFirebugConsoleElement(context, win);
+        if (element)
+            element.setAttribute("FirebugVersion", Firebug.version); // Initialize Firebug version.
+        else
+            return false;
+
+        var handler = new FirebugConsoleHandler(context, win);
+        handler.attachTo(element);
+
+        context.activeConsoleHandlers.push(handler);
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("consoleInjector addConsoleListener attached handler("+handler.handler_name+") to _firebugConsole in : "+win.location+"\n");
+        return true;
+    },
+
+    detachConsole: function(context, win)
+    {
+        if (win && win.document)
+        {
+            var element = win.document.getElementById("_firebugConsole");
+            if (element)
+                element.parentNode.removeChild(element);
+        }
+    }
+};
+
+var total_handlers = 0;
+var FirebugConsoleHandler = function FirebugConsoleHandler(context, win)
+{
+    this.window = win;
+
+    this.attachTo = function(element)
+    {
+        this.element = element;
+        // When raised on our injected element, callback to Firebug and append to console
+        this.boundHandler = bind(this.handleEvent, this);
+        this.element.addEventListener('firebugAppendConsole', this.boundHandler, true); // capturing
+    };
+
+    this.detach = function()
+    {
+        this.element.removeEventListener('firebugAppendConsole', this.boundHandler, true);
+    };
+
+    this.handler_name = ++total_handlers;
+    this.handleEvent = function(event)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("FirebugConsoleHandler("+this.handler_name+") "+event.target.getAttribute("methodName")+", event", event);
+        if (!Firebug.CommandLine.CommandHandler.handle(event, this, win))
+        {
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("FirebugConsoleHandler", this);
+
+            var methodName = event.target.getAttribute("methodName");
+            Firebug.Console.log($STRF("console.MethodNotSupported", [methodName]));
+        }
+    };
+
+    this.firebuglite = Firebug.version;
+
+    this.init = function()
+    {
+        var consoleElement = win.document.getElementById('_firebugConsole');
+        consoleElement.setAttribute("FirebugVersion", Firebug.version);
+    };
+
+    this.log = function()
+    {
+        logFormatted(arguments, "log");
+    };
+
+    this.debug = function()
+    {
+        logFormatted(arguments, "debug", true);
+    };
+
+    this.info = function()
+    {
+        logFormatted(arguments, "info", true);
+    };
+
+    this.warn = function()
+    {
+        logFormatted(arguments, "warn", true);
+    };
+
+    this.error = function()
+    {
+        //TODO: xxxpedro console error
+        //if (arguments.length == 1)
+        //{
+        //    logAssert("error", arguments);  // add more info based on stack trace
+        //}
+        //else
+        //{
+            //Firebug.Errors.increaseCount(context);
+            logFormatted(arguments, "error", true);  // user already added info
+        //}
+    };
+
+    this.exception = function()
+    {
+        logAssert("error", arguments);
+    };
+
+    this.assert = function(x)
+    {
+        if (!x)
+        {
+            var rest = [];
+            for (var i = 1; i < arguments.length; i++)
+                rest.push(arguments[i]);
+            logAssert("assert", rest);
+        }
+    };
+
+    this.dir = function(o)
+    {
+        Firebug.Console.log(o, context, "dir", Firebug.DOMPanel.DirTable);
+    };
+
+    this.dirxml = function(o)
+    {
+        ///if (o instanceof Window)
+        if (instanceOf(o, "Window"))
+            o = o.document.documentElement;
+        ///else if (o instanceof Document)
+        else if (instanceOf(o, "Document"))
+            o = o.documentElement;
+
+        Firebug.Console.log(o, context, "dirxml", Firebug.HTMLPanel.SoloElement);
+    };
+
+    this.group = function()
+    {
+        //TODO: xxxpedro;
+        //var sourceLink = getStackLink();
+        var sourceLink = null;
+        Firebug.Console.openGroup(arguments, null, "group", null, false, sourceLink);
+    };
+
+    this.groupEnd = function()
+    {
+        Firebug.Console.closeGroup(context);
+    };
+
+    this.groupCollapsed = function()
+    {
+        var sourceLink = getStackLink();
+        // noThrottle true is probably ok, openGroups will likely be short strings.
+        var row = Firebug.Console.openGroup(arguments, null, "group", null, true, sourceLink);
+        removeClass(row, "opened");
+    };
+
+    this.profile = function(title)
+    {
+        logFormatted(["console.profile() not supported."], "warn", true);
+
+        //Firebug.Profiler.startProfiling(context, title);
+    };
+
+    this.profileEnd = function()
+    {
+        logFormatted(["console.profile() not supported."], "warn", true);
+
+        //Firebug.Profiler.stopProfiling(context);
+    };
+
+    this.count = function(key)
+    {
+        // TODO: xxxpedro console2: is there a better way to find a unique ID for the coun() call?
+        var frameId = "0";
+        //var frameId = FBL.getStackFrameId();
+        if (frameId)
+        {
+            if (!frameCounters)
+                frameCounters = {};
+
+            if (key != undefined)
+                frameId += key;
+
+            var frameCounter = frameCounters[frameId];
+            if (!frameCounter)
+            {
+                var logRow = logFormatted(["0"], null, true, true);
+
+                frameCounter = {logRow: logRow, count: 1};
+                frameCounters[frameId] = frameCounter;
+            }
+            else
+                ++frameCounter.count;
+
+            var label = key == undefined
+                ? frameCounter.count
+                : key + " " + frameCounter.count;
+
+            frameCounter.logRow.firstChild.firstChild.nodeValue = label;
+        }
+    };
+
+    this.trace = function()
+    {
+        var getFuncName = function getFuncName (f)
+        {
+            if (f.getName instanceof Function)
+            {
+                return f.getName();
+            }
+            if (f.name) // in FireFox, Function objects have a name property...
+            {
+                return f.name;
+            }
+
+            var name = f.toString().match(/function\s*([_$\w\d]*)/)[1];
+            return name || "anonymous";
+        };
+
+        var wasVisited = function(fn)
+        {
+            for (var i=0, l=frames.length; i<l; i++)
+            {
+                if (frames[i].fn == fn)
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        };
+
+        traceRecursion++;
+
+        if (traceRecursion > 1)
+        {
+            traceRecursion--;
+            return;
+        }
+
+        var frames = [];
+
+        for (var fn = arguments.callee.caller.caller; fn; fn = fn.caller)
+        {
+            if (wasVisited(fn)) break;
+
+            var args = [];
+
+            for (var i = 0, l = fn.arguments.length; i < l; ++i)
+            {
+                args.push({value: fn.arguments[i]});
+            }
+
+            frames.push({fn: fn, name: getFuncName(fn), args: args});
+        }
+
+
+        // ****************************************************************************************
+
+        try
+        {
+            (0)();
+        }
+        catch(e)
+        {
+            var result = e;
+
+            var stack =
+                result.stack || // Firefox / Google Chrome
+                result.stacktrace || // Opera
+                "";
+
+            stack = stack.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks
+            var items = stack.split(/[\n\r]/);
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            // Google Chrome
+            if (FBL.isSafari)
+            {
+                //var reChromeStackItem = /^\s+at\s+([^\(]+)\s\((.*)\)$/;
+                //var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/;
+                var reChromeStackItem = /^\s+at\s+(.*)((?:http|https|ftp|file):\/\/.*)$/;
+
+                var reChromeStackItemName = /\s*\($/;
+                var reChromeStackItemValue = /^(.+)\:(\d+\:\d+)\)?$/;
+
+                var framePos = 0;
+                for (var i=4, length=items.length; i<length; i++, framePos++)
+                {
+                    var frame = frames[framePos];
+                    var item = items[i];
+                    var match = item.match(reChromeStackItem);
+
+                    //Firebug.Console.log("["+ framePos +"]--------------------------");
+                    //Firebug.Console.log(item);
+                    //Firebug.Console.log("................");
+
+                    if (match)
+                    {
+                        var name = match[1];
+                        if (name)
+                        {
+                            name = name.replace(reChromeStackItemName, "");
+                            frame.name = name;
+                        }
+
+                        //Firebug.Console.log("name: "+name);
+
+                        var value = match[2].match(reChromeStackItemValue);
+                        if (value)
+                        {
+                            frame.href = value[1];
+                            frame.lineNo = value[2];
+
+                            //Firebug.Console.log("url: "+value[1]);
+                            //Firebug.Console.log("line: "+value[2]);
+                        }
+                        //else
+                        //    Firebug.Console.log(match[2]);
+
+                    }
+                }
+            }
+            /**/
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            else if (FBL.isFirefox)
+            {
+                // Firefox
+                var reFirefoxStackItem = /^(.*)@(.*)$/;
+                var reFirefoxStackItemValue = /^(.+)\:(\d+)$/;
+
+                var framePos = 0;
+                for (var i=2, length=items.length; i<length; i++, framePos++)
+                {
+                    var frame = frames[framePos] || {};
+                    var item = items[i];
+                    var match = item.match(reFirefoxStackItem);
+
+                    if (match)
+                    {
+                        var name = match[1];
+
+                        //Firebug.Console.logFormatted("name: "+name);
+
+                        var value = match[2].match(reFirefoxStackItemValue);
+                        if (value)
+                        {
+                            frame.href = value[1];
+                            frame.lineNo = value[2];
+
+                            //Firebug.Console.log("href: "+ value[1]);
+                            //Firebug.Console.log("line: " + value[2]);
+                        }
+                        //else
+                        //    Firebug.Console.logFormatted([match[2]]);
+                    }
+                }
+            }
+            /**/
+
+            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+            /*
+            else if (FBL.isOpera)
+            {
+                // Opera
+                var reOperaStackItem = /^\s\s(?:\.\.\.\s\s)?Line\s(\d+)\sof\s(.+)$/;
+                var reOperaStackItemValue = /^linked\sscript\s(.+)$/;
+
+                for (var i=0, length=items.length; i<length; i+=2)
+                {
+                    var item = items[i];
+
+                    var match = item.match(reOperaStackItem);
+
+                    if (match)
+                    {
+                        //Firebug.Console.log(match[1]);
+
+                        var value = match[2].match(reOperaStackItemValue);
+
+                        if (value)
+                        {
+                            //Firebug.Console.log(value[1]);
+                        }
+                        //else
+                        //    Firebug.Console.log(match[2]);
+
+                        //Firebug.Console.log("--------------------------");
+                    }
+                }
+            }
+            /**/
+        }
+
+        //console.log(stack);
+        //console.dir(frames);
+        Firebug.Console.log({frames: frames}, context, "stackTrace", FirebugReps.StackTrace);
+
+        traceRecursion--;
+    };
+
+    this.trace_ok = function()
+    {
+        var getFuncName = function getFuncName (f)
+        {
+            if (f.getName instanceof Function)
+                return f.getName();
+            if (f.name) // in FireFox, Function objects have a name property...
+                return f.name;
+
+            var name = f.toString().match(/function\s*([_$\w\d]*)/)[1];
+            return name || "anonymous";
+        };
+
+        var wasVisited = function(fn)
+        {
+            for (var i=0, l=frames.length; i<l; i++)
+            {
+                if (frames[i].fn == fn)
+                    return true;
+            }
+
+            return false;
+        };
+
+        var frames = [];
+
+        for (var fn = arguments.callee.caller; fn; fn = fn.caller)
+        {
+            if (wasVisited(fn)) break;
+
+            var args = [];
+
+            for (var i = 0, l = fn.arguments.length; i < l; ++i)
+            {
+                args.push({value: fn.arguments[i]});
+            }
+
+            frames.push({fn: fn, name: getFuncName(fn), args: args});
+        }
+
+        Firebug.Console.log({frames: frames}, context, "stackTrace", FirebugReps.StackTrace);
+    };
+
+    this.clear = function()
+    {
+        Firebug.Console.clear(context);
+    };
+
+    this.time = function(name, reset)
+    {
+        if (!name)
+            return;
+
+        var time = new Date().getTime();
+
+        if (!this.timeCounters)
+            this.timeCounters = {};
+
+        var key = "KEY"+name.toString();
+
+        if (!reset && this.timeCounters[key])
+            return;
+
+        this.timeCounters[key] = time;
+    };
+
+    this.timeEnd = function(name)
+    {
+        var time = new Date().getTime();
+
+        if (!this.timeCounters)
+            return;
+
+        var key = "KEY"+name.toString();
+
+        var timeCounter = this.timeCounters[key];
+        if (timeCounter)
+        {
+            var diff = time - timeCounter;
+            var label = name + ": " + diff + "ms";
+
+            this.info(label);
+
+            delete this.timeCounters[key];
+        }
+        return diff;
+    };
+
+    // These functions are over-ridden by commandLine
+    this.evaluated = function(result, context)
+    {
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("consoleInjector.FirebugConsoleHandler evalutated default called", result);
+
+        Firebug.Console.log(result, context);
+    };
+    this.evaluateError = function(result, context)
+    {
+        Firebug.Console.log(result, context, "errorMessage");
+    };
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    function logFormatted(args, className, linkToSource, noThrottle)
+    {
+        var sourceLink = linkToSource ? getStackLink() : null;
+        return Firebug.Console.logFormatted(args, context, className, noThrottle, sourceLink);
+    }
+
+    function logAssert(category, args)
+    {
+        Firebug.Errors.increaseCount(context);
+
+        if (!args || !args.length || args.length == 0)
+            var msg = [FBL.$STR("Assertion")];
+        else
+            var msg = args[0];
+
+        if (Firebug.errorStackTrace)
+        {
+            var trace = Firebug.errorStackTrace;
+            delete Firebug.errorStackTrace;
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("logAssert trace from errorStackTrace", trace);
+        }
+        else if (msg.stack)
+        {
+            var trace = parseToStackTrace(msg.stack);
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("logAssert trace from msg.stack", trace);
+        }
+        else
+        {
+            var trace = getJSDUserStack();
+            if (FBTrace.DBG_CONSOLE)
+                FBTrace.sysout("logAssert trace from getJSDUserStack", trace);
+        }
+
+        var errorObject = new FBL.ErrorMessage(msg, (msg.fileName?msg.fileName:win.location), (msg.lineNumber?msg.lineNumber:0), "", category, context, trace);
+
+
+        if (trace && trace.frames && trace.frames[0])
+           errorObject.correctWithStackTrace(trace);
+
+        errorObject.resetSource();
+
+        var objects = errorObject;
+        if (args.length > 1)
+        {
+            objects = [errorObject];
+            for (var i = 1; i < args.length; i++)
+                objects.push(args[i]);
+        }
+
+        var row = Firebug.Console.log(objects, context, "errorMessage", null, true); // noThrottle
+        row.scrollIntoView();
+    }
+
+    function getComponentsStackDump()
+    {
+        // Starting with our stack, walk back to the user-level code
+        var frame = Components.stack;
+        var userURL = win.location.href.toString();
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("consoleInjector.getComponentsStackDump initial stack for userURL "+userURL, frame);
+
+        // Drop frames until we get into user code.
+        while (frame && FBL.isSystemURL(frame.filename) )
+            frame = frame.caller;
+
+        // Drop two more frames, the injected console function and firebugAppendConsole()
+        if (frame)
+            frame = frame.caller;
+        if (frame)
+            frame = frame.caller;
+
+        if (FBTrace.DBG_CONSOLE)
+            FBTrace.sysout("consoleInjector.getComponentsStackDump final stack for userURL "+userURL, frame);
+
+        return frame;
+    }
+
+    function getStackLink()
+    {
+        // TODO: xxxpedro console2
+        return;
+        //return FBL.getFrameSourceLink(getComponentsStackDump());
+    }
+
+    function getJSDUserStack()
+    {
+        var trace = FBL.getCurrentStackTrace(context);
+
+        var frames = trace ? trace.frames : null;
+        if (frames && (frames.length > 0) )
+        {
+            var oldest = frames.length - 1;  // 6 - 1 = 5
+            for (var i = 0; i < frames.length; i++)
+            {
+                if (frames[oldest - i].href.indexOf("chrome:") == 0) break;
+                var fn = frames[oldest - i].fn + "";
+                if (fn && (fn.indexOf("_firebugEvalEvent") != -1) ) break;  // command line
+            }
+            FBTrace.sysout("consoleInjector getJSDUserStack: "+frames.length+" oldest: "+oldest+" i: "+i+" i - oldest + 2: "+(i - oldest + 2), trace);
+            trace.frames = trace.frames.slice(2 - i);  // take the oldest frames, leave 2 behind they are injection code
+
+            return trace;
+        }
+        else
+            return "Firebug failed to get stack trace with any frames";
+    }
+};
+
+// ************************************************************************************************
+// Register console namespace
+
+FBL.registerConsole = function()
+{
+    var win = Env.browser.window;
+    Firebug.Console.injector.install(win);
+};
+
+registerConsole();
+
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+
+// ************************************************************************************************
+// Globals
+
+var commandPrefix = ">>>";
+var reOpenBracket = /[\[\(\{]/;
+var reCloseBracket = /[\]\)\}]/;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var commandHistory = [];
+var commandPointer = -1;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var isAutoCompleting = null;
+var autoCompletePrefix = null;
+var autoCompleteExpr = null;
+var autoCompleteBuffer = null;
+var autoCompletePosition = null;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var fbCommandLine = null;
+var fbLargeCommandLine = null;
+var fbLargeCommandButtons = null;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var _completion =
+{
+    window:
+    [
+        "console"
+    ],
+
+    document:
+    [
+        "getElementById",
+        "getElementsByTagName"
+    ]
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var _stack = function(command)
+{
+    Firebug.context.persistedState.commandHistory.push(command);
+    Firebug.context.persistedState.commandPointer =
+        Firebug.context.persistedState.commandHistory.length;
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+// ************************************************************************************************
+// CommandLine
+
+Firebug.CommandLine = extend(Firebug.Module,
+{
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    element: null,
+    isMultiLine: false,
+    isActive: false,
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    initialize: function(doc)
+    {
+        this.clear = bind(this.clear, this);
+        this.enter = bind(this.enter, this);
+
+        this.onError = bind(this.onError, this);
+        this.onKeyDown = bind(this.onKeyDown, this);
+        this.onMultiLineKeyDown = bind(this.onMultiLineKeyDown, this);
+
+        addEvent(Firebug.browser.window, "error", this.onError);
+        addEvent(Firebug.chrome.window, "error", this.onError);
+    },
+
+    shutdown: function(doc)
+    {
+        this.deactivate();
+
+        removeEvent(Firebug.browser.window, "error", this.onError);
+        removeEvent(Firebug.chrome.window, "error", this.onError);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    activate: function(multiLine, hideToggleIcon, onRun)
+    {
+        defineCommandLineAPI();
+
+         Firebug.context.persistedState.commandHistory =
+             Firebug.context.persistedState.commandHistory || [];
+
+         Firebug.context.persistedState.commandPointer =
+             Firebug.context.persistedState.commandPointer || -1;
+
+        if (this.isActive)
+        {
+            if (this.isMultiLine == multiLine) return;
+
+            this.deactivate();
+        }
+
+        fbCommandLine = $("fbCommandLine");
+        fbLargeCommandLine = $("fbLargeCommandLine");
+        fbLargeCommandButtons = $("fbLargeCommandButtons");
+
+        if (multiLine)
+        {
+            onRun = onRun || this.enter;
+
+            this.isMultiLine = true;
+
+            this.element = fbLargeCommandLine;
+
+            addEvent(this.element, "keydown", this.onMultiLineKeyDown);
+
+            addEvent($("fbSmallCommandLineIcon"), "click", Firebug.chrome.hideLargeCommandLine);
+
+            this.runButton = new Button({
+                element: $("fbCommand_btRun"),
+                owner: Firebug.CommandLine,
+                onClick: onRun
+            });
+
+            this.runButton.initialize();
+
+            this.clearButton = new Button({
+                element: $("fbCommand_btClear"),
+                owner: Firebug.CommandLine,
+                onClick: this.clear
+            });
+
+            this.clearButton.initialize();
+        }
+        else
+        {
+            this.isMultiLine = false;
+            this.element = fbCommandLine;
+
+            if (!fbCommandLine)
+                return;
+
+            addEvent(this.element, "keydown", this.onKeyDown);
+        }
+
+        //Firebug.Console.log("activate", this.element);
+
+        if (isOpera)
+          fixOperaTabKey(this.element);
+
+        if(this.lastValue)
+            this.element.value = this.lastValue;
+
+        this.isActive = true;
+    },
+
+    deactivate: function()
+    {
+        if (!this.isActive) return;
+
+        //Firebug.Console.log("deactivate", this.element);
+
+        this.isActive = false;
+
+        this.lastValue = this.element.value;
+
+        if (this.isMultiLine)
+        {
+            removeEvent(this.element, "keydown", this.onMultiLineKeyDown);
+
+            removeEvent($("fbSmallCommandLineIcon"), "click", Firebug.chrome.hideLargeCommandLine);
+
+            this.runButton.destroy();
+            this.clearButton.destroy();
+        }
+        else
+        {
+            removeEvent(this.element, "keydown", this.onKeyDown);
+        }
+
+        this.element = null;
+        delete this.element;
+
+        fbCommandLine = null;
+        fbLargeCommandLine = null;
+        fbLargeCommandButtons = null;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    focus: function()
+    {
+        this.element.focus();
+    },
+
+    blur: function()
+    {
+        this.element.blur();
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    clear: function()
+    {
+        this.element.value = "";
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    evaluate: function(expr)
+    {
+        // TODO: need to register the API in console.firebug.commandLineAPI
+        var api = "Firebug.CommandLine.API";
+
+        var result = Firebug.context.evaluate(expr, "window", api, Firebug.Console.error);
+
+        return result;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    enter: function()
+    {
+        var command = this.element.value;
+
+        if (!command) return;
+
+        _stack(command);
+
+        Firebug.Console.log(commandPrefix + " " + stripNewLines(command),
+                Firebug.browser, "command", FirebugReps.Text);
+
+        var result = this.evaluate(command);
+
+        Firebug.Console.log(result);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    prevCommand: function()
+    {
+        if (Firebug.context.persistedState.commandPointer > 0 &&
+            Firebug.context.persistedState.commandHistory.length > 0)
+        {
+            this.element.value = Firebug.context.persistedState.commandHistory
+                                    [--Firebug.context.persistedState.commandPointer];
+        }
+    },
+
+    nextCommand: function()
+    {
+        var element = this.element;
+
+        var limit = Firebug.context.persistedState.commandHistory.length -1;
+        var i = Firebug.context.persistedState.commandPointer;
+
+        if (i < limit)
+          element.value = Firebug.context.persistedState.commandHistory
+                              [++Firebug.context.persistedState.commandPointer];
+
+        else if (i == limit)
+        {
+            ++Firebug.context.persistedState.commandPointer;
+            element.value = "";
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    autocomplete: function(reverse)
+    {
+        var element = this.element;
+
+        var command = element.value;
+        var offset = getExpressionOffset(command);
+
+        var valBegin = offset ? command.substr(0, offset) : "";
+        var val = command.substr(offset);
+
+        var buffer, obj, objName, commandBegin, result, prefix;
+
+        // if it is the beginning of the completion
+        if(!isAutoCompleting)
+        {
+
+            // group1 - command begin
+            // group2 - base object
+            // group3 - property prefix
+            var reObj = /(.*[^_$\w\d\.])?((?:[_$\w][_$\w\d]*\.)*)([_$\w][_$\w\d]*)?$/;
+            var r = reObj.exec(val);
+
+            // parse command
+            if (r[1] || r[2] || r[3])
+            {
+                commandBegin = r[1] || "";
+                objName = r[2] || "";
+                prefix = r[3] || "";
+            }
+            else if (val == "")
+            {
+                commandBegin = objName = prefix = "";
+            } else
+                return;
+
+            isAutoCompleting = true;
+
+            // find base object
+            if(objName == "")
+                obj = window;
+
+            else
+            {
+                objName = objName.replace(/\.$/, "");
+
+                var n = objName.split(".");
+                var target = window, o;
+
+                for (var i=0, ni; ni = n[i]; i++)
+                {
+                    if (o = target[ni])
+                      target = o;
+
+                    else
+                    {
+                        target = null;
+                        break;
+                    }
+                }
+                obj = target;
+            }
+
+            // map base object
+            if(obj)
+            {
+                autoCompletePrefix = prefix;
+                autoCompleteExpr = valBegin + commandBegin + (objName ? objName + "." : "");
+                autoCompletePosition = -1;
+
+                buffer = autoCompleteBuffer = isIE ?
+                    _completion[objName || "window"] || [] : [];
+
+                for(var p in obj)
+                    buffer.push(p);
+            }
+
+        // if it is the continuation of the last completion
+        } else
+          buffer = autoCompleteBuffer;
+
+        if (buffer)
+        {
+            prefix = autoCompletePrefix;
+
+            var diff = reverse ? -1 : 1;
+
+            for(var i=autoCompletePosition+diff, l=buffer.length, bi; i>=0 && i<l; i+=diff)
+            {
+                bi = buffer[i];
+
+                if (bi.indexOf(prefix) == 0)
+                {
+                    autoCompletePosition = i;
+                    result = bi;
+                    break;
+                }
+            }
+        }
+
+        if (result)
+            element.value = autoCompleteExpr + result;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    setMultiLine: function(multiLine)
+    {
+        if (multiLine == this.isMultiLine) return;
+
+        this.activate(multiLine);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onError: function(msg, href, lineNo)
+    {
+        href = href || "";
+
+        var lastSlash = href.lastIndexOf("/");
+        var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
+        var html = [
+            '<span class="errorMessage">', msg, '</span>',
+            '<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
+          ];
+
+        // TODO: xxxpedro ajust to Console2
+        //Firebug.Console.writeRow(html, "error");
+    },
+
+    onKeyDown: function(e)
+    {
+        e = e || event;
+
+        var code = e.keyCode;
+
+        /*tab, shift, control, alt*/
+        if (code != 9 && code != 16 && code != 17 && code != 18)
+        {
+            isAutoCompleting = false;
+        }
+
+        if (code == 13 /* enter */)
+        {
+            this.enter();
+            this.clear();
+        }
+        else if (code == 27 /* ESC */)
+        {
+            setTimeout(this.clear, 0);
+        }
+        else if (code == 38 /* up */)
+        {
+            this.prevCommand();
+        }
+        else if (code == 40 /* down */)
+        {
+            this.nextCommand();
+        }
+        else if (code == 9 /* tab */)
+        {
+            this.autocomplete(e.shiftKey);
+        }
+        else
+            return;
+
+        cancelEvent(e, true);
+        return false;
+    },
+
+    onMultiLineKeyDown: function(e)
+    {
+        e = e || event;
+
+        var code = e.keyCode;
+
+        if (code == 13 /* enter */ && e.ctrlKey)
+        {
+            this.enter();
+        }
+    }
+});
+
+Firebug.registerModule(Firebug.CommandLine);
+
+
+// ************************************************************************************************
+//
+
+function getExpressionOffset(command)
+{
+    // XXXjoe This is kind of a poor-man's JavaScript parser - trying
+    // to find the start of the expression that the cursor is inside.
+    // Not 100% fool proof, but hey...
+
+    var bracketCount = 0;
+
+    var start = command.length-1;
+    for (; start >= 0; --start)
+    {
+        var c = command[start];
+        if ((c == "," || c == ";" || c == " ") && !bracketCount)
+            break;
+        if (reOpenBracket.test(c))
+        {
+            if (bracketCount)
+                --bracketCount;
+            else
+                break;
+        }
+        else if (reCloseBracket.test(c))
+            ++bracketCount;
+    }
+
+    return start + 1;
+}
+
+// ************************************************************************************************
+// CommandLine API
+
+var CommandLineAPI =
+{
+    $: function(id)
+    {
+        return Firebug.browser.document.getElementById(id);
+    },
+
+    $$: function(selector, context)
+    {
+        context = context || Firebug.browser.document;
+        return Firebug.Selector ?
+                Firebug.Selector(selector, context) :
+                Firebug.Console.error("Firebug.Selector module not loaded.");
+    },
+
+    $0: null,
+
+    $1: null,
+
+    dir: function(o)
+    {
+        Firebug.Console.log(o, Firebug.context, "dir", Firebug.DOMPanel.DirTable);
+    },
+
+    dirxml: function(o)
+    {
+        ///if (o instanceof Window)
+        if (instanceOf(o, "Window"))
+            o = o.document.documentElement;
+        ///else if (o instanceof Document)
+        else if (instanceOf(o, "Document"))
+            o = o.documentElement;
+
+        Firebug.Console.log(o, Firebug.context, "dirxml", Firebug.HTMLPanel.SoloElement);
+    }
+};
+
+// ************************************************************************************************
+
+var defineCommandLineAPI = function defineCommandLineAPI()
+{
+    Firebug.CommandLine.API = {};
+    for (var m in CommandLineAPI)
+        if (!Env.browser.window[m])
+            Firebug.CommandLine.API[m] = CommandLineAPI[m];
+
+    var stack = FirebugChrome.htmlSelectionStack;
+    if (stack)
+    {
+        Firebug.CommandLine.API.$0 = stack[0];
+        Firebug.CommandLine.API.$1 = stack[1];
+    }
+};
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Globals
+
+var ElementCache = Firebug.Lite.Cache.Element;
+var cacheID = Firebug.Lite.Cache.ID;
+
+var ignoreHTMLProps =
+{
+    // ignores the attributes injected by Sizzle, otherwise it will
+    // be visible on IE (when enumerating element.attributes)
+    sizcache: 1,
+    sizset: 1
+};
+
+if (Firebug.ignoreFirebugElements)
+    // ignores also the cache property injected by firebug
+    ignoreHTMLProps[cacheID] = 1;
+
+
+// ************************************************************************************************
+// HTML Module
+
+Firebug.HTML = extend(Firebug.Module,
+{
+    appendTreeNode: function(nodeArray, html)
+    {
+        var reTrim = /^\s+|\s+$/g;
+
+        if (!nodeArray.length) nodeArray = [nodeArray];
+
+        for (var n=0, node; node=nodeArray[n]; n++)
+        {
+            if (node.nodeType == 1)
+            {
+                if (Firebug.ignoreFirebugElements && node.firebugIgnore) continue;
+
+                var uid = ElementCache(node);
+                var child = node.childNodes;
+                var childLength = child.length;
+
+                var nodeName = node.nodeName.toLowerCase();
+
+                var nodeVisible = isVisible(node);
+
+                var hasSingleTextChild = childLength == 1 && node.firstChild.nodeType == 3 &&
+                        nodeName != "script" && nodeName != "style";
+
+                var nodeControl = !hasSingleTextChild && childLength > 0 ?
+                    ('<div class="nodeControl"></div>') : '';
+
+                // FIXME xxxpedro remove this
+                //var isIE = false;
+
+                if(isIE && nodeControl)
+                    html.push(nodeControl);
+
+                if (typeof uid != 'undefined')
+                    html.push(
+                        '<div class="objectBox-element" ',
+                        'id="', uid,
+                        '">',
+                        !isIE && nodeControl ? nodeControl: "",
+                        '<span ',
+                        cacheID,
+                        '="', uid,
+                        '"  class="nodeBox',
+                        nodeVisible ? "" : " nodeHidden",
+                        '">&lt;<span class="nodeTag">', nodeName, '</span>'
+                    );
+                else
+                    html.push(
+                        '<div class="objectBox-element"><span class="nodeBox',
+                        nodeVisible ? "" : " nodeHidden",
+                        '">&lt;<span class="nodeTag">',
+                        nodeName, '</span>'
+                    );
+
+                for (var i = 0; i < node.attributes.length; ++i)
+                {
+                    var attr = node.attributes[i];
+                    if (!attr.specified ||
+                        // Issue 4432:  Firebug Lite: HTML is mixed-up with functions
+                        // The problem here is that expando properties added to DOM elements in
+                        // IE < 9 will behave like DOM attributes and so they'll show up when
+                        // looking at element.attributes list.
+                        isIE && (browserVersion-0<9) && typeof attr.nodeValue != "string" ||
+                        Firebug.ignoreFirebugElements && ignoreHTMLProps.hasOwnProperty(attr.nodeName))
+                            continue;
+
+                    var name = attr.nodeName.toLowerCase();
+                    var value = name == "style" ? formatStyles(node.style.cssText) : attr.nodeValue;
+
+                    html.push('&nbsp;<span class="nodeName">', name,
+                        '</span>=&quot;<span class="nodeValue">', escapeHTML(value),
+                        '</span>&quot;');
+                }
+
+                /*
+                // source code nodes
+                if (nodeName == 'script' || nodeName == 'style')
+                {
+
+                    if(document.all){
+                        var src = node.innerHTML+'\n';
+
+                    }else {
+                        var src = '\n'+node.innerHTML+'\n';
+                    }
+
+                    var match = src.match(/\n/g);
+                    var num = match ? match.length : 0;
+                    var s = [], sl = 0;
+
+                    for(var c=1; c<num; c++){
+                        s[sl++] = '<div line="'+c+'">' + c + '</div>';
+                    }
+
+                    html.push('&gt;</div><div class="nodeGroup"><div class="nodeChildren"><div class="lineNo">',
+                            s.join(''),
+                            '</div><pre class="nodeCode">',
+                            escapeHTML(src),
+                            '</pre>',
+                            '</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
+                            nodeName,
+                            '</span>&gt;</div>',
+                            '</div>'
+                        );
+
+
+                }/**/
+
+                // Just a single text node child
+                if (hasSingleTextChild)
+                {
+                    var value = child[0].nodeValue.replace(reTrim, '');
+                    if(value)
+                    {
+                        html.push(
+                                '&gt;<span class="nodeText">',
+                                escapeHTML(value),
+                                '</span>&lt;/<span class="nodeTag">',
+                                nodeName,
+                                '</span>&gt;</span></div>'
+                            );
+                    }
+                    else
+                      html.push('/&gt;</span></div>'); // blank text, print as childless node
+
+                }
+                else if (childLength > 0)
+                {
+                    html.push('&gt;</span></div>');
+                }
+                else
+                    html.push('/&gt;</span></div>');
+
+            }
+            else if (node.nodeType == 3)
+            {
+                if ( node.parentNode && ( node.parentNode.nodeName.toLowerCase() == "script" ||
+                     node.parentNode.nodeName.toLowerCase() == "style" ) )
+                {
+                    var value = node.nodeValue.replace(reTrim, '');
+
+                    if(isIE){
+                        var src = value+'\n';
+
+                    }else {
+                        var src = '\n'+value+'\n';
+                    }
+
+                    var match = src.match(/\n/g);
+                    var num = match ? match.length : 0;
+                    var s = [], sl = 0;
+
+                    for(var c=1; c<num; c++){
+                        s[sl++] = '<div line="'+c+'">' + c + '</div>';
+                    }
+
+                    html.push('<div class="lineNo">',
+                            s.join(''),
+                            '</div><pre class="sourceCode">',
+                            escapeHTML(src),
+                            '</pre>'
+                        );
+
+                }
+                else
+                {
+                    var value = node.nodeValue.replace(reTrim, '');
+                    if (value)
+                        html.push('<div class="nodeText">', escapeHTML(value),'</div>');
+                }
+            }
+        }
+    },
+
+    appendTreeChildren: function(treeNode)
+    {
+        var doc = Firebug.chrome.document;
+        var uid = treeNode.id;
+        var parentNode = ElementCache.get(uid);
+
+        if (parentNode.childNodes.length == 0) return;
+
+        var treeNext = treeNode.nextSibling;
+        var treeParent = treeNode.parentNode;
+
+        // FIXME xxxpedro remove this
+        //var isIE = false;
+        var control = isIE ? treeNode.previousSibling : treeNode.firstChild;
+        control.className = 'nodeControl nodeMaximized';
+
+        var html = [];
+        var children = doc.createElement("div");
+        children.className = "nodeChildren";
+        this.appendTreeNode(parentNode.childNodes, html);
+        children.innerHTML = html.join("");
+
+        treeParent.insertBefore(children, treeNext);
+
+        var closeElement = doc.createElement("div");
+        closeElement.className = "objectBox-element";
+        closeElement.innerHTML = '&lt;/<span class="nodeTag">' +
+            parentNode.nodeName.toLowerCase() + '&gt;</span>';
+
+        treeParent.insertBefore(closeElement, treeNext);
+
+    },
+
+    removeTreeChildren: function(treeNode)
+    {
+        var children = treeNode.nextSibling;
+        var closeTag = children.nextSibling;
+
+        // FIXME xxxpedro remove this
+        //var isIE = false;
+        var control = isIE ? treeNode.previousSibling : treeNode.firstChild;
+        control.className = 'nodeControl';
+
+        children.parentNode.removeChild(children);
+        closeTag.parentNode.removeChild(closeTag);
+    },
+
+    isTreeNodeVisible: function(id)
+    {
+        return $(id);
+    },
+
+    select: function(el)
+    {
+        var id = el && ElementCache(el);
+        if (id)
+            this.selectTreeNode(id);
+    },
+
+    selectTreeNode: function(id)
+    {
+        id = ""+id;
+        var node, stack = [];
+        while(id && !this.isTreeNodeVisible(id))
+        {
+            stack.push(id);
+
+            var node = ElementCache.get(id).parentNode;
+
+            if (node)
+                id = ElementCache(node);
+            else
+                break;
+        }
+
+        stack.push(id);
+
+        while(stack.length > 0)
+        {
+            id = stack.pop();
+            node = $(id);
+
+            if (stack.length > 0 && ElementCache.get(id).childNodes.length > 0)
+              this.appendTreeChildren(node);
+        }
+
+        selectElement(node);
+
+        // TODO: xxxpedro
+        if (fbPanel1)
+            fbPanel1.scrollTop = Math.round(node.offsetTop - fbPanel1.clientHeight/2);
+    }
+
+});
+
+Firebug.registerModule(Firebug.HTML);
+
+// ************************************************************************************************
+// HTML Panel
+
+function HTMLPanel(){};
+
+HTMLPanel.prototype = extend(Firebug.Panel,
+{
+    name: "HTML",
+    title: "HTML",
+
+    options: {
+        hasSidePanel: true,
+        //hasToolButtons: true,
+        isPreRendered: !Firebug.flexChromeEnabled /* FIXME xxxpedro chromenew */,
+        innerHTMLSync: true
+    },
+
+    create: function(){
+        Firebug.Panel.create.apply(this, arguments);
+
+        this.panelNode.style.padding = "4px 3px 1px 15px";
+        this.panelNode.style.minWidth = "500px";
+
+        if (Env.Options.enablePersistent || Firebug.chrome.type != "popup")
+            this.createUI();
+
+        if(this.sidePanelBar && !this.sidePanelBar.selectedPanel)
+        {
+            this.sidePanelBar.selectPanel("css");
+        }
+    },
+
+    destroy: function()
+    {
+        selectedElement = null;
+        fbPanel1 = null;
+
+        selectedSidePanelTS = null;
+        selectedSidePanelTimer = null;
+
+        Firebug.Panel.destroy.apply(this, arguments);
+    },
+
+    createUI: function()
+    {
+        var rootNode = Firebug.browser.document.documentElement;
+        var html = [];
+        Firebug.HTML.appendTreeNode(rootNode, html);
+
+        this.panelNode.innerHTML = html.join("");
+    },
+
+    initialize: function()
+    {
+        Firebug.Panel.initialize.apply(this, arguments);
+        addEvent(this.panelNode, 'click', Firebug.HTML.onTreeClick);
+
+        fbPanel1 = $("fbPanel1");
+
+        if(!selectedElement)
+        {
+            Firebug.context.persistedState.selectedHTMLElementId =
+                Firebug.context.persistedState.selectedHTMLElementId &&
+                ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId) ?
+                Firebug.context.persistedState.selectedHTMLElementId :
+                ElementCache(Firebug.browser.document.body);
+
+            Firebug.HTML.selectTreeNode(Firebug.context.persistedState.selectedHTMLElementId);
+        }
+
+        // TODO: xxxpedro
+        addEvent(fbPanel1, 'mousemove', Firebug.HTML.onListMouseMove);
+        addEvent($("fbContent"), 'mouseout', Firebug.HTML.onListMouseMove);
+        addEvent(Firebug.chrome.node, 'mouseout', Firebug.HTML.onListMouseMove);
+    },
+
+    shutdown: function()
+    {
+        // TODO: xxxpedro
+        removeEvent(fbPanel1, 'mousemove', Firebug.HTML.onListMouseMove);
+        removeEvent($("fbContent"), 'mouseout', Firebug.HTML.onListMouseMove);
+        removeEvent(Firebug.chrome.node, 'mouseout', Firebug.HTML.onListMouseMove);
+
+        removeEvent(this.panelNode, 'click', Firebug.HTML.onTreeClick);
+
+        fbPanel1 = null;
+
+        Firebug.Panel.shutdown.apply(this, arguments);
+    },
+
+    reattach: function()
+    {
+        // TODO: panel reattach
+        if(Firebug.context.persistedState.selectedHTMLElementId)
+            Firebug.HTML.selectTreeNode(Firebug.context.persistedState.selectedHTMLElementId);
+    },
+
+    updateSelection: function(object)
+    {
+        var id = ElementCache(object);
+
+        if (id)
+        {
+            Firebug.HTML.selectTreeNode(id);
+        }
+    }
+});
+
+Firebug.registerPanel(HTMLPanel);
+
+// ************************************************************************************************
+
+var formatStyles = function(styles)
+{
+    return isIE ?
+        // IE return CSS property names in upper case, so we need to convert them
+        styles.replace(/([^\s]+)\s*:/g, function(m,g){return g.toLowerCase()+":";}) :
+        // other browsers are just fine
+        styles;
+};
+
+// ************************************************************************************************
+
+var selectedElement = null;
+var fbPanel1 = null;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+var selectedSidePanelTS, selectedSidePanelTimer;
+
+var selectElement= function selectElement(e)
+{
+    if (e != selectedElement)
+    {
+        if (selectedElement)
+            selectedElement.className = "objectBox-element";
+
+        e.className = e.className + " selectedElement";
+
+        if (FBL.isFirefox)
+            e.style.MozBorderRadius = "2px";
+
+        else if (FBL.isSafari)
+            e.style.WebkitBorderRadius = "2px";
+
+        e.style.borderRadius = "2px";
+
+        selectedElement = e;
+
+        Firebug.context.persistedState.selectedHTMLElementId = e.id;
+
+        var target = ElementCache.get(e.id);
+        var sidePanelBar = Firebug.chrome.getPanel("HTML").sidePanelBar;
+        var selectedSidePanel = sidePanelBar ? sidePanelBar.selectedPanel : null;
+
+        var stack = FirebugChrome.htmlSelectionStack;
+
+        stack.unshift(target);
+
+        if (stack.length > 2)
+            stack.pop();
+
+        var lazySelect = function()
+        {
+            selectedSidePanelTS = new Date().getTime();
+
+            if (selectedSidePanel)
+                selectedSidePanel.select(target, true);
+        };
+
+        if (selectedSidePanelTimer)
+        {
+            clearTimeout(selectedSidePanelTimer);
+            selectedSidePanelTimer = null;
+        }
+
+        if (new Date().getTime() - selectedSidePanelTS > 100)
+            setTimeout(lazySelect, 0);
+        else
+            selectedSidePanelTimer = setTimeout(lazySelect, 150);
+    }
+};
+
+
+// ************************************************************************************************
+// ***  TODO:  REFACTOR  **************************************************************************
+// ************************************************************************************************
+Firebug.HTML.onTreeClick = function (e)
+{
+    e = e || event;
+    var targ;
+
+    if (e.target) targ = e.target;
+    else if (e.srcElement) targ = e.srcElement;
+    if (targ.nodeType == 3) // defeat Safari bug
+        targ = targ.parentNode;
+
+
+    if (targ.className.indexOf('nodeControl') != -1 || targ.className == 'nodeTag')
+    {
+        // FIXME xxxpedro remove this
+        //var isIE = false;
+
+        if(targ.className == 'nodeTag')
+        {
+            var control = isIE ? (targ.parentNode.previousSibling || targ) :
+                          (targ.parentNode.previousSibling || targ);
+
+            selectElement(targ.parentNode.parentNode);
+
+            if (control.className.indexOf('nodeControl') == -1)
+                return;
+
+        } else
+            control = targ;
+
+        FBL.cancelEvent(e);
+
+        var treeNode = isIE ? control.nextSibling : control.parentNode;
+
+        //FBL.Firebug.Console.log(treeNode);
+
+        if (control.className.indexOf(' nodeMaximized') != -1) {
+            FBL.Firebug.HTML.removeTreeChildren(treeNode);
+        } else {
+            FBL.Firebug.HTML.appendTreeChildren(treeNode);
+        }
+    }
+    else if (targ.className == 'nodeValue' || targ.className == 'nodeName')
+    {
+        /*
+        var input = FBL.Firebug.chrome.document.getElementById('treeInput');
+
+        input.style.display = "block";
+        input.style.left = targ.offsetLeft + 'px';
+        input.style.top = FBL.topHeight + targ.offsetTop - FBL.fbPanel1.scrollTop + 'px';
+        input.style.width = targ.offsetWidth + 6 + 'px';
+        input.value = targ.textContent || targ.innerText;
+        input.focus();
+        /**/
+    }
+};
+
+function onListMouseOut(e)
+{
+    e = e || event || window;
+    var targ;
+
+    if (e.target) targ = e.target;
+    else if (e.srcElement) targ = e.srcElement;
+    if (targ.nodeType == 3) // defeat Safari bug
+      targ = targ.parentNode;
+
+      if (hasClass(targ, "fbPanel")) {
+          FBL.Firebug.Inspector.hideBoxModel();
+          hoverElement = null;
+      }
+};
+
+var hoverElement = null;
+var hoverElementTS = 0;
+
+Firebug.HTML.onListMouseMove = function onListMouseMove(e)
+{
+    try
+    {
+        e = e || event || window;
+        var targ;
+
+        if (e.target) targ = e.target;
+        else if (e.srcElement) targ = e.srcElement;
+        if (targ.nodeType == 3) // defeat Safari bug
+            targ = targ.parentNode;
+
+        var found = false;
+        while (targ && !found) {
+            if (!/\snodeBox\s|\sobjectBox-selector\s/.test(" " + targ.className + " "))
+                targ = targ.parentNode;
+            else
+                found = true;
+        }
+
+        if (!targ)
+        {
+            FBL.Firebug.Inspector.hideBoxModel();
+            hoverElement = null;
+            return;
+        }
+
+        /*
+        if (typeof targ.attributes[cacheID] == 'undefined') return;
+
+        var uid = targ.attributes[cacheID];
+        if (!uid) return;
+        /**/
+
+        if (typeof targ.attributes[cacheID] == 'undefined') return;
+
+        var uid = targ.attributes[cacheID];
+        if (!uid) return;
+
+        var el = ElementCache.get(uid.value);
+
+        var nodeName = el.nodeName.toLowerCase();
+
+        if (FBL.isIE && " meta title script link ".indexOf(" "+nodeName+" ") != -1)
+            return;
+
+        if (!/\snodeBox\s|\sobjectBox-selector\s/.test(" " + targ.className + " ")) return;
+
+        if (el.id == "FirebugUI" || " html head body br script link iframe ".indexOf(" "+nodeName+" ") != -1) {
+            FBL.Firebug.Inspector.hideBoxModel();
+            hoverElement = null;
+            return;
+        }
+
+        if ((new Date().getTime() - hoverElementTS > 40) && hoverElement != el) {
+            hoverElementTS = new Date().getTime();
+            hoverElement = el;
+            FBL.Firebug.Inspector.drawBoxModel(el);
+        }
+    }
+    catch(E)
+    {
+    }
+};
+
+
+// ************************************************************************************************
+
+Firebug.Reps = {
+
+    appendText: function(object, html)
+    {
+        html.push(escapeHTML(objectToString(object)));
+    },
+
+    appendNull: function(object, html)
+    {
+        html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
+    },
+
+    appendString: function(object, html)
+    {
+        html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
+            '&quot;</span>');
+    },
+
+    appendInteger: function(object, html)
+    {
+        html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+    },
+
+    appendFloat: function(object, html)
+    {
+        html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
+    },
+
+    appendFunction: function(object, html)
+    {
+        var reName = /function ?(.*?)\(/;
+        var m = reName.exec(objectToString(object));
+        var name = m && m[1] ? m[1] : "function";
+        html.push('<span class="objectBox-function">', escapeHTML(name), '()</span>');
+    },
+
+    appendObject: function(object, html)
+    {
+        /*
+        var rep = Firebug.getRep(object);
+        var outputs = [];
+
+        rep.tag.tag.compile();
+
+        var str = rep.tag.renderHTML({object: object}, outputs);
+        html.push(str);
+        /**/
+
+        try
+        {
+            if (object == undefined)
+                this.appendNull("undefined", html);
+            else if (object == null)
+                this.appendNull("null", html);
+            else if (typeof object == "string")
+                this.appendString(object, html);
+            else if (typeof object == "number")
+                this.appendInteger(object, html);
+            else if (typeof object == "boolean")
+                this.appendInteger(object, html);
+            else if (typeof object == "function")
+                this.appendFunction(object, html);
+            else if (object.nodeType == 1)
+                this.appendSelector(object, html);
+            else if (typeof object == "object")
+            {
+                if (typeof object.length != "undefined")
+                    this.appendArray(object, html);
+                else
+                    this.appendObjectFormatted(object, html);
+            }
+            else
+                this.appendText(object, html);
+        }
+        catch (exc)
+        {
+        }
+        /**/
+    },
+
+    appendObjectFormatted: function(object, html)
+    {
+        var text = objectToString(object);
+        var reObject = /\[object (.*?)\]/;
+
+        var m = reObject.exec(text);
+        html.push('<span class="objectBox-object">', m ? m[1] : text, '</span>');
+    },
+
+    appendSelector: function(object, html)
+    {
+        var uid = ElementCache(object);
+        var uidString = uid ? [cacheID, '="', uid, '"'].join("") : "";
+
+        html.push('<span class="objectBox-selector"', uidString, '>');
+
+        html.push('<span class="selectorTag">', escapeHTML(object.nodeName.toLowerCase()), '</span>');
+        if (object.id)
+            html.push('<span class="selectorId">#', escapeHTML(object.id), '</span>');
+        if (object.className)
+            html.push('<span class="selectorClass">.', escapeHTML(object.className), '</span>');
+
+        html.push('</span>');
+    },
+
+    appendNode: function(node, html)
+    {
+        if (node.nodeType == 1)
+        {
+            var uid = ElementCache(node);
+            var uidString = uid ? [cacheID, '="', uid, '"'].join("") : "";
+
+            html.push(
+                '<div class="objectBox-element"', uidString, '">',
+                '<span ', cacheID, '="', uid, '" class="nodeBox">',
+                '&lt;<span class="nodeTag">', node.nodeName.toLowerCase(), '</span>');
+
+            for (var i = 0; i < node.attributes.length; ++i)
+            {
+                var attr = node.attributes[i];
+                if (!attr.specified || attr.nodeName == cacheID)
+                    continue;
+
+                var name = attr.nodeName.toLowerCase();
+                var value = name == "style" ? node.style.cssText : attr.nodeValue;
+
+                html.push('&nbsp;<span class="nodeName">', name,
+                    '</span>=&quot;<span class="nodeValue">', escapeHTML(value),
+                    '</span>&quot;');
+            }
+
+            if (node.firstChild)
+            {
+                html.push('&gt;</div><div class="nodeChildren">');
+
+                for (var child = node.firstChild; child; child = child.nextSibling)
+                    this.appendNode(child, html);
+
+                html.push('</div><div class="objectBox-element">&lt;/<span class="nodeTag">',
+                    node.nodeName.toLowerCase(), '&gt;</span></span></div>');
+            }
+            else
+                html.push('/&gt;</span></div>');
+        }
+        else if (node.nodeType == 3)
+        {
+            var value = trim(node.nodeValue);
+            if (value)
+                html.push('<div class="nodeText">', escapeHTML(value),'</div>');
+        }
+    },
+
+    appendArray: function(object, html)
+    {
+        html.push('<span class="objectBox-array"><b>[</b> ');
+
+        for (var i = 0, l = object.length, obj; i < l; ++i)
+        {
+            this.appendObject(object[i], html);
+
+            if (i < l-1)
+            html.push(', ');
+        }
+
+        html.push(' <b>]</b></span>');
+    }
+
+};
+
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+/*
+
+Hack:
+Firebug.chrome.currentPanel = Firebug.chrome.selectedPanel;
+Firebug.showInfoTips = true;
+Firebug.InfoTip.initializeBrowser(Firebug.chrome);
+
+/**/
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// Constants
+
+var maxWidth = 100, maxHeight = 80;
+var infoTipMargin = 10;
+var infoTipWindowPadding = 25;
+
+// ************************************************************************************************
+
+Firebug.InfoTip = extend(Firebug.Module,
+{
+    dispatchName: "infoTip",
+    tags: domplate(
+    {
+        infoTipTag: DIV({"class": "infoTip"}),
+
+        colorTag:
+            DIV({style: "background: $rgbValue; width: 100px; height: 40px"}, "&nbsp;"),
+
+        imgTag:
+            DIV({"class": "infoTipImageBox infoTipLoading"},
+                IMG({"class": "infoTipImage", src: "$urlValue", repeat: "$repeat",
+                    onload: "$onLoadImage"}),
+                IMG({"class": "infoTipBgImage", collapsed: true, src: "blank.gif"}),
+                DIV({"class": "infoTipCaption"})
+            ),
+
+        onLoadImage: function(event)
+        {
+            var img = event.currentTarget || event.srcElement;
+            ///var bgImg = img.nextSibling;
+            ///if (!bgImg)
+            ///    return; // Sometimes gets called after element is dead
+
+            ///var caption = bgImg.nextSibling;
+            var innerBox = img.parentNode;
+
+            /// TODO: xxxpedro infoTip hack
+            var caption = getElementByClass(innerBox, "infoTipCaption");
+            var bgImg = getElementByClass(innerBox, "infoTipBgImage");
+            if (!bgImg)
+                return; // Sometimes gets called after element is dead
+
+            // TODO: xxxpedro infoTip IE and timing issue
+            // TODO: use offline document to avoid flickering
+            if (isIE)
+                removeClass(innerBox, "infoTipLoading");
+
+            var updateInfoTip = function(){
+
+            var w = img.naturalWidth || img.width || 10,
+                h = img.naturalHeight || img.height || 10;
+
+            var repeat = img.getAttribute("repeat");
+
+            if (repeat == "repeat-x" || (w == 1 && h > 1))
+            {
+                collapse(img, true);
+                collapse(bgImg, false);
+                bgImg.style.background = "url(" + img.src + ") repeat-x";
+                bgImg.style.width = maxWidth + "px";
+                if (h > maxHeight)
+                    bgImg.style.height = maxHeight + "px";
+                else
+                    bgImg.style.height = h + "px";
+            }
+            else if (repeat == "repeat-y" || (h == 1 && w > 1))
+            {
+                collapse(img, true);
+                collapse(bgImg, false);
+                bgImg.style.background = "url(" + img.src + ") repeat-y";
+                bgImg.style.height = maxHeight + "px";
+                if (w > maxWidth)
+                    bgImg.style.width = maxWidth + "px";
+                else
+                    bgImg.style.width = w + "px";
+            }
+            else if (repeat == "repeat" || (w == 1 && h == 1))
+            {
+                collapse(img, true);
+                collapse(bgImg, false);
+                bgImg.style.background = "url(" + img.src + ") repeat";
+                bgImg.style.width = maxWidth + "px";
+                bgImg.style.height = maxHeight + "px";
+            }
+            else
+            {
+                if (w > maxWidth || h > maxHeight)
+                {
+                    if (w > h)
+                    {
+                        img.style.width = maxWidth + "px";
+                        img.style.height = Math.round((h / w) * maxWidth) + "px";
+                    }
+                    else
+                    {
+                        img.style.width = Math.round((w / h) * maxHeight) + "px";
+                        img.style.height = maxHeight + "px";
+                    }
+                }
+            }
+
+            //caption.innerHTML = $STRF("Dimensions", [w, h]);
+            caption.innerHTML = $STRF(w + " x " + h);
+
+
+            };
+
+            if (isIE)
+                setTimeout(updateInfoTip, 0);
+            else
+            {
+                updateInfoTip();
+                removeClass(innerBox, "infoTipLoading");
+            }
+
+            ///
+        }
+
+        /*
+        /// onLoadImage original
+        onLoadImage: function(event)
+        {
+            var img = event.currentTarget;
+            var bgImg = img.nextSibling;
+            if (!bgImg)
+                return; // Sometimes gets called after element is dead
+
+            var caption = bgImg.nextSibling;
+            var innerBox = img.parentNode;
+
+            var w = img.naturalWidth, h = img.naturalHeight;
+            var repeat = img.getAttribute("repeat");
+
+            if (repeat == "repeat-x" || (w == 1 && h > 1))
+            {
+                collapse(img, true);
+                collapse(bgImg, false);
+                bgImg.style.background = "url(" + img.src + ") repeat-x";
+                bgImg.style.width = maxWidth + "px";
+                if (h > maxHeight)
+                    bgImg.style.height = maxHeight + "px";
+                else
+                    bgImg.style.height = h + "px";
+            }
+            else if (repeat == "repeat-y" || (h == 1 && w > 1))
+            {
+                collapse(img, true);
+                collapse(bgImg, false);
+                bgImg.style.background = "url(" + img.src + ") repeat-y";
+                bgImg.style.height = maxHeight + "px";
+                if (w > maxWidth)
+                    bgImg.style.width = maxWidth + "px";
+                else
+                    bgImg.style.width = w + "px";
+            }
+            else if (repeat == "repeat" || (w == 1 && h == 1))
+            {
+                collapse(img, true);
+                collapse(bgImg, false);
+                bgImg.style.background = "url(" + img.src + ") repeat";
+                bgImg.style.width = maxWidth + "px";
+                bgImg.style.height = maxHeight + "px";
+            }
+            else
+            {
+                if (w > maxWidth || h > maxHeight)
+                {
+                    if (w > h)
+                    {
+                        img.style.width = maxWidth + "px";
+                        img.style.height = Math.round((h / w) * maxWidth) + "px";
+                    }
+                    else
+                    {
+                        img.style.width = Math.round((w / h) * maxHeight) + "px";
+                        img.style.height = maxHeight + "px";
+                    }
+                }
+            }
+
+            caption.innerHTML = $STRF("Dimensions", [w, h]);
+
+            removeClass(innerBox, "infoTipLoading");
+        }
+        /**/
+
+    }),
+
+    initializeBrowser: function(browser)
+    {
+        browser.onInfoTipMouseOut = bind(this.onMouseOut, this, browser);
+        browser.onInfoTipMouseMove = bind(this.onMouseMove, this, browser);
+
+        ///var doc = browser.contentDocument;
+        var doc = browser.document;
+        if (!doc)
+            return;
+
+        ///doc.addEventListener("mouseover", browser.onInfoTipMouseMove, true);
+        ///doc.addEventListener("mouseout", browser.onInfoTipMouseOut, true);
+        ///doc.addEventListener("mousemove", browser.onInfoTipMouseMove, true);
+        addEvent(doc, "mouseover", browser.onInfoTipMouseMove);
+        addEvent(doc, "mouseout", browser.onInfoTipMouseOut);
+        addEvent(doc, "mousemove", browser.onInfoTipMouseMove);
+
+        return browser.infoTip = this.tags.infoTipTag.append({}, getBody(doc));
+    },
+
+    uninitializeBrowser: function(browser)
+    {
+        if (browser.infoTip)
+        {
+            ///var doc = browser.contentDocument;
+            var doc = browser.document;
+            ///doc.removeEventListener("mouseover", browser.onInfoTipMouseMove, true);
+            ///doc.removeEventListener("mouseout", browser.onInfoTipMouseOut, true);
+            ///doc.removeEventListener("mousemove", browser.onInfoTipMouseMove, true);
+            removeEvent(doc, "mouseover", browser.onInfoTipMouseMove);
+            removeEvent(doc, "mouseout", browser.onInfoTipMouseOut);
+            removeEvent(doc, "mousemove", browser.onInfoTipMouseMove);
+
+            browser.infoTip.parentNode.removeChild(browser.infoTip);
+            delete browser.infoTip;
+            delete browser.onInfoTipMouseMove;
+        }
+    },
+
+    showInfoTip: function(infoTip, panel, target, x, y, rangeParent, rangeOffset)
+    {
+        if (!Firebug.showInfoTips)
+            return;
+
+        var scrollParent = getOverflowParent(target);
+        var scrollX = x + (scrollParent ? scrollParent.scrollLeft : 0);
+
+        if (panel.showInfoTip(infoTip, target, scrollX, y, rangeParent, rangeOffset))
+        {
+            var htmlElt = infoTip.ownerDocument.documentElement;
+            var panelWidth = htmlElt.clientWidth;
+            var panelHeight = htmlElt.clientHeight;
+
+            if (x+infoTip.offsetWidth+infoTipMargin > panelWidth)
+            {
+                infoTip.style.left = Math.max(0, panelWidth-(infoTip.offsetWidth+infoTipMargin)) + "px";
+                infoTip.style.right = "auto";
+            }
+            else
+            {
+                infoTip.style.left = (x+infoTipMargin) + "px";
+                infoTip.style.right = "auto";
+            }
+
+            if (y+infoTip.offsetHeight+infoTipMargin > panelHeight)
+            {
+                infoTip.style.top = Math.max(0, panelHeight-(infoTip.offsetHeight+infoTipMargin)) + "px";
+                infoTip.style.bottom = "auto";
+            }
+            else
+            {
+                infoTip.style.top = (y+infoTipMargin) + "px";
+                infoTip.style.bottom = "auto";
+            }
+
+            if (FBTrace.DBG_INFOTIP)
+                FBTrace.sysout("infotip.showInfoTip; top: " + infoTip.style.top +
+                    ", left: " + infoTip.style.left + ", bottom: " + infoTip.style.bottom +
+                    ", right:" + infoTip.style.right + ", offsetHeight: " + infoTip.offsetHeight +
+                    ", offsetWidth: " + infoTip.offsetWidth +
+                    ", x: " + x + ", panelWidth: " + panelWidth +
+                    ", y: " + y + ", panelHeight: " + panelHeight);
+
+            infoTip.setAttribute("active", "true");
+        }
+        else
+            this.hideInfoTip(infoTip);
+    },
+
+    hideInfoTip: function(infoTip)
+    {
+        if (infoTip)
+            infoTip.removeAttribute("active");
+    },
+
+    onMouseOut: function(event, browser)
+    {
+        if (!event.relatedTarget)
+            this.hideInfoTip(browser.infoTip);
+    },
+
+    onMouseMove: function(event, browser)
+    {
+        // Ignore if the mouse is moving over the existing info tip.
+        if (getAncestorByClass(event.target, "infoTip"))
+            return;
+
+        if (browser.currentPanel)
+        {
+            var x = event.clientX, y = event.clientY, target = event.target || event.srcElement;
+            this.showInfoTip(browser.infoTip, browser.currentPanel, target, x, y, event.rangeParent, event.rangeOffset);
+        }
+        else
+            this.hideInfoTip(browser.infoTip);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    populateColorInfoTip: function(infoTip, color)
+    {
+        this.tags.colorTag.replace({rgbValue: color}, infoTip);
+        return true;
+    },
+
+    populateImageInfoTip: function(infoTip, url, repeat)
+    {
+        if (!repeat)
+            repeat = "no-repeat";
+
+        this.tags.imgTag.replace({urlValue: url, repeat: repeat}, infoTip);
+
+        return true;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Module
+
+    disable: function()
+    {
+        // XXXjoe For each browser, call uninitializeBrowser
+    },
+
+    showPanel: function(browser, panel)
+    {
+        if (panel)
+        {
+            var infoTip = panel.panelBrowser.infoTip;
+            if (!infoTip)
+                infoTip = this.initializeBrowser(panel.panelBrowser);
+            this.hideInfoTip(infoTip);
+        }
+
+    },
+
+    showSidePanel: function(browser, panel)
+    {
+        this.showPanel(browser, panel);
+    }
+});
+
+// ************************************************************************************************
+
+Firebug.registerModule(Firebug.InfoTip);
+
+// ************************************************************************************************
+
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+var CssParser = null;
+
+// ************************************************************************************************
+
+// Simple CSS stylesheet parser from:
+// https://github.com/sergeche/webkit-css
+
+/**
+ * Simple CSS stylesheet parser that remembers rule's lines in file
+ * @author Sergey Chikuyonok (serge.che@gmail.com)
+ * @link http://chikuyonok.ru
+ */
+CssParser = (function(){
+    /**
+     * Returns rule object
+     * @param {Number} start Character index where CSS rule definition starts
+     * @param {Number} body_start Character index where CSS rule's body starts
+     * @param {Number} end Character index where CSS rule definition ends
+     */
+    function rule(start, body_start, end) {
+        return {
+            start: start || 0,
+            body_start: body_start || 0,
+            end: end || 0,
+            line: -1,
+            selector: null,
+            parent: null,
+
+            /** @type {rule[]} */
+            children: [],
+
+            addChild: function(start, body_start, end) {
+                var r = rule(start, body_start, end);
+                r.parent = this;
+                this.children.push(r);
+                return r;
+            },
+            /**
+             * Returns last child element
+             * @return {rule}
+             */
+            lastChild: function() {
+                return this.children[this.children.length - 1];
+            }
+        };
+    }
+
+    /**
+     * Replaces all occurances of substring defined by regexp
+     * @param {String} str
+     * @return {RegExp} re
+     * @return {String}
+     */
+    function removeAll(str, re) {
+        var m;
+        while (m = str.match(re)) {
+            str = str.substring(m[0].length);
+        }
+
+        return str;
+    }
+
+    /**
+     * Trims whitespace from the beginning and the end of string
+     * @param {String} str
+     * @return {String}
+     */
+    function trim(str) {
+        return str.replace(/^\s+|\s+$/g, '');
+    }
+
+    /**
+     * Normalizes CSS rules selector
+     * @param {String} selector
+     */
+    function normalizeSelector(selector) {
+        // remove newlines
+        selector = selector.replace(/[\n\r]/g, ' ');
+
+        selector = trim(selector);
+
+        // remove spaces after commas
+        selector = selector.replace(/\s*,\s*/g, ',');
+
+        return selector;
+    }
+
+    /**
+     * Preprocesses parsed rules: adjusts char indexes, skipping whitespace and
+     * newlines, saves rule selector, removes comments, etc.
+     * @param {String} text CSS stylesheet
+     * @param {rule} rule_node CSS rule node
+     * @return {rule[]}
+     */
+    function preprocessRules(text, rule_node) {
+        for (var i = 0, il = rule_node.children.length; i < il; i++) {
+            var r = rule_node.children[i],
+                rule_start = text.substring(r.start, r.body_start),
+                cur_len = rule_start.length;
+
+            // remove newlines for better regexp matching
+            rule_start = rule_start.replace(/[\n\r]/g, ' ');
+
+            // remove @import rules
+//            rule_start = removeAll(rule_start, /^\s*@import\s*url\((['"])?.+?\1?\)\;?/g);
+
+            // remove comments
+            rule_start = removeAll(rule_start, /^\s*\/\*.*?\*\/[\s\t]*/);
+
+            // remove whitespace
+            rule_start = rule_start.replace(/^[\s\t]+/, '');
+
+            r.start += (cur_len - rule_start.length);
+            r.selector = normalizeSelector(rule_start);
+        }
+
+        return rule_node;
+    }
+
+    /**
+     * Saves all lise starting indexes for faster search
+     * @param {String} text CSS stylesheet
+     * @return {Number[]}
+     */
+    function saveLineIndexes(text) {
+        var result = [0],
+            i = 0,
+            il = text.length,
+            ch, ch2;
+
+        while (i < il) {
+            ch = text.charAt(i);
+
+            if (ch == '\n' || ch == '\r') {
+                if (ch == '\r' && i < il - 1 && text.charAt(i + 1) == '\n') {
+                    // windows line ending: CRLF. Skip next character
+                    i++;
+                }
+
+                result.push(i + 1);
+            }
+
+            i++;
+        }
+
+        return result;
+    }
+
+    /**
+     * Saves line number for parsed rules
+     * @param {String} text CSS stylesheet
+     * @param {rule} rule_node Rule node
+     * @return {rule[]}
+     */
+    function saveLineNumbers(text, rule_node, line_indexes, startLine) {
+        preprocessRules(text, rule_node);
+
+        startLine = startLine || 0;
+
+        // remember lines start indexes, preserving line ending characters
+        if (!line_indexes)
+            var line_indexes = saveLineIndexes(text);
+
+        // now find each rule's line
+        for (var i = 0, il = rule_node.children.length; i < il; i++) {
+            var r = rule_node.children[i];
+            r.line = line_indexes.length + startLine;
+            for (var j = 0, jl = line_indexes.length - 1; j < jl; j++) {
+                var line_ix = line_indexes[j];
+                if (r.start >=  line_indexes[j] && r.start <  line_indexes[j + 1]) {
+                    r.line = j + 1 + startLine;
+                    break;
+                }
+            }
+
+            saveLineNumbers(text, r, line_indexes);
+        }
+
+        return rule_node;
+    }
+
+    return {
+        /**
+         * Parses text as CSS stylesheet, remembring each rule position inside
+         * text
+         * @param {String} text CSS stylesheet to parse
+         */
+        read: function(text, startLine) {
+            var rule_start = [],
+                rule_body_start = [],
+                rules = [],
+                in_comment = 0,
+                root = rule(),
+                cur_parent = root,
+                last_rule = null,
+                stack = [],
+                ch, ch2;
+
+            stack.last = function() {
+                return this[this.length - 1];
+            };
+
+            function hasStr(pos, substr) {
+                return text.substr(pos, substr.length) == substr;
+            }
+
+            for (var i = 0, il = text.length; i < il; i++) {
+                ch = text.charAt(i);
+                ch2 = i < il - 1 ? text.charAt(i + 1) : '';
+
+                if (!rule_start.length)
+                    rule_start.push(i);
+
+                switch (ch) {
+                    case '@':
+                        if (!in_comment) {
+                            if (hasStr(i, '@import')) {
+                                var m = text.substr(i).match(/^@import\s*url\((['"])?.+?\1?\)\;?/);
+                                if (m) {
+                                    cur_parent.addChild(i, i + 7, i + m[0].length);
+                                    i += m[0].length;
+                                    rule_start.pop();
+                                }
+                                break;
+                            }
+                        }
+                    case '/':
+                        // xxxpedro allowing comment inside comment
+                        if (!in_comment && ch2 == '*') { // comment start
+                            in_comment++;
+                        }
+                        break;
+
+                    case '*':
+                        if (ch2 == '/') { // comment end
+                            in_comment--;
+                        }
+                        break;
+
+                    case '{':
+                        if (!in_comment) {
+                            rule_body_start.push(i);
+
+                            cur_parent = cur_parent.addChild(rule_start.pop());
+                            stack.push(cur_parent);
+                        }
+                        break;
+
+                    case '}':
+                        // found the end of the rule
+                        if (!in_comment) {
+                            /** @type {rule} */
+                            var last_rule = stack.pop();
+                            rule_start.pop();
+                            last_rule.body_start = rule_body_start.pop();
+                            last_rule.end = i;
+                            cur_parent = last_rule.parent || root;
+                        }
+                        break;
+                }
+
+            }
+
+            return saveLineNumbers(text, root, null, startLine);
+        },
+
+        normalizeSelector: normalizeSelector,
+
+        /**
+         * Find matched rule by selector.
+         * @param {rule} rule_node Parsed rule node
+         * @param {String} selector CSS selector
+         * @param {String} source CSS stylesheet source code
+         *
+         * @return {rule[]|null} Array of matched rules, sorted by priority (most
+         * recent on top)
+         */
+        findBySelector: function(rule_node, selector, source) {
+            var selector = normalizeSelector(selector),
+                result = [];
+
+            if (rule_node) {
+                for (var i = 0, il = rule_node.children.length; i < il; i++) {
+                    /** @type {rule} */
+                    var r = rule_node.children[i];
+                    if (r.selector == selector) {
+                        result.push(r);
+                    }
+                }
+            }
+
+            if (result.length) {
+                return result;
+            } else {
+                return null;
+            }
+        }
+    };
+})();
+
+
+// ************************************************************************************************
+
+FBL.CssParser = CssParser;
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// StyleSheet Parser
+
+var CssAnalyzer = {};
+
+// ************************************************************************************************
+// Locals
+
+var CSSRuleMap = {};
+var ElementCSSRulesMap = {};
+
+var internalStyleSheetIndex = -1;
+
+var reSelectorTag = /(^|\s)(?:\w+)/g;
+var reSelectorClass = /\.[\w\d_-]+/g;
+var reSelectorId = /#[\w\d_-]+/g;
+
+var globalCSSRuleIndex;
+
+var processAllStyleSheetsTimeout = null;
+
+var externalStyleSheetURLs = [];
+
+var ElementCache = Firebug.Lite.Cache.Element;
+var StyleSheetCache = Firebug.Lite.Cache.StyleSheet;
+
+//************************************************************************************************
+// CSS Analyzer templates
+
+CssAnalyzer.externalStyleSheetWarning = domplate(Firebug.Rep,
+{
+    tag:
+        DIV({"class": "warning focusRow", style: "font-weight:normal;", role: 'listitem'},
+            SPAN("$object|STR"),
+            A({"href": "$href", target:"_blank"}, "$link|STR")
+        )
+});
+
+// ************************************************************************************************
+// CSS Analyzer methods
+
+CssAnalyzer.processAllStyleSheets = function(doc, styleSheetIterator)
+{
+    try
+    {
+        processAllStyleSheets(doc, styleSheetIterator);
+    }
+    catch(e)
+    {
+        // TODO: FBTrace condition
+        FBTrace.sysout("CssAnalyzer.processAllStyleSheets fails: ", e);
+    }
+};
+
+/**
+ *
+ * @param element
+ * @returns {String[]} Array of IDs of CSS Rules
+ */
+CssAnalyzer.getElementCSSRules = function(element)
+{
+    try
+    {
+        return getElementCSSRules(element);
+    }
+    catch(e)
+    {
+        // TODO: FBTrace condition
+        FBTrace.sysout("CssAnalyzer.getElementCSSRules fails: ", e);
+    }
+};
+
+CssAnalyzer.getRuleData = function(ruleId)
+{
+    return CSSRuleMap[ruleId];
+};
+
+// TODO: do we need this?
+CssAnalyzer.getRuleLine = function()
+{
+};
+
+CssAnalyzer.hasExternalStyleSheet = function()
+{
+    return externalStyleSheetURLs.length > 0;
+};
+
+CssAnalyzer.parseStyleSheet = function(href)
+{
+    var sourceData = extractSourceData(href);
+    var parsedObj = CssParser.read(sourceData.source, sourceData.startLine);
+    var parsedRules = parsedObj.children;
+
+    // See: Issue 4776: [Firebug lite] CSS Media Types
+    //
+    // Ignore all special selectors like @media and @page
+    for(var i=0; i < parsedRules.length; )
+    {
+        if (parsedRules[i].selector.indexOf("@") != -1)
+        {
+            parsedRules.splice(i, 1);
+        }
+        else
+            i++;
+    }
+
+    return parsedRules;
+};
+
+//************************************************************************************************
+// Internals
+//************************************************************************************************
+
+// ************************************************************************************************
+// StyleSheet processing
+
+var processAllStyleSheets = function(doc, styleSheetIterator)
+{
+    styleSheetIterator = styleSheetIterator || processStyleSheet;
+
+    globalCSSRuleIndex = -1;
+
+    var styleSheets = doc.styleSheets;
+    var importedStyleSheets = [];
+
+    if (FBTrace.DBG_CSS)
+        var start = new Date().getTime();
+
+    for(var i=0, length=styleSheets.length; i<length; i++)
+    {
+        try
+        {
+            var styleSheet = styleSheets[i];
+
+            if ("firebugIgnore" in styleSheet) continue;
+
+            // we must read the length to make sure we have permission to read
+            // the stylesheet's content. If an error occurs here, we cannot
+            // read the stylesheet due to access restriction policy
+            var rules = isIE ? styleSheet.rules : styleSheet.cssRules;
+            rules.length;
+        }
+        catch(e)
+        {
+            externalStyleSheetURLs.push(styleSheet.href);
+            styleSheet.restricted = true;
+            var ssid = StyleSheetCache(styleSheet);
+
+            /// TODO: xxxpedro external css
+            //loadExternalStylesheet(doc, styleSheetIterator, styleSheet);
+        }
+
+        // process internal and external styleSheets
+        styleSheetIterator(doc, styleSheet);
+
+        var importedStyleSheet, importedRules;
+
+        // process imported styleSheets in IE
+        if (isIE)
+        {
+            var imports = styleSheet.imports;
+
+            for(var j=0, importsLength=imports.length; j<importsLength; j++)
+            {
+                try
+                {
+                    importedStyleSheet = imports[j];
+                    // we must read the length to make sure we have permission
+                    // to read the imported stylesheet's content.
+                    importedRules = importedStyleSheet.rules;
+                    importedRules.length;
+                }
+                catch(e)
+                {
+                    externalStyleSheetURLs.push(styleSheet.href);
+                    importedStyleSheet.restricted = true;
+                    var ssid = StyleSheetCache(importedStyleSheet);
+                }
+
+                styleSheetIterator(doc, importedStyleSheet);
+            }
+        }
+        // process imported styleSheets in other browsers
+        else if (rules)
+        {
+            for(var j=0, rulesLength=rules.length; j<rulesLength; j++)
+            {
+                try
+                {
+                    var rule = rules[j];
+
+                    importedStyleSheet = rule.styleSheet;
+
+                    if (importedStyleSheet)
+                    {
+                        // we must read the length to make sure we have permission
+                        // to read the imported stylesheet's content.
+                        importedRules = importedStyleSheet.cssRules;
+                        importedRules.length;
+                    }
+                    else
+                        break;
+                }
+                catch(e)
+                {
+                    externalStyleSheetURLs.push(styleSheet.href);
+                    importedStyleSheet.restricted = true;
+                    var ssid = StyleSheetCache(importedStyleSheet);
+                }
+
+                styleSheetIterator(doc, importedStyleSheet);
+            }
+        }
+    };
+
+    if (FBTrace.DBG_CSS)
+    {
+        FBTrace.sysout("FBL.processAllStyleSheets", "all stylesheet rules processed in " + (new Date().getTime() - start) + "ms");
+    }
+};
+
+// ************************************************************************************************
+
+var processStyleSheet = function(doc, styleSheet)
+{
+    if (styleSheet.restricted)
+        return;
+
+    var rules = isIE ? styleSheet.rules : styleSheet.cssRules;
+
+    var ssid = StyleSheetCache(styleSheet);
+
+    var href = styleSheet.href;
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // CSS Parser
+    var shouldParseCSS = typeof CssParser != "undefined" && !Firebug.disableResourceFetching;
+    if (shouldParseCSS)
+    {
+        try
+        {
+            var parsedRules = CssAnalyzer.parseStyleSheet(href);
+        }
+        catch(e)
+        {
+            if (FBTrace.DBG_ERRORS) FBTrace.sysout("processStyleSheet FAILS", e.message || e);
+            shouldParseCSS = false;
+        }
+        finally
+        {
+            var parsedRulesIndex = 0;
+
+            var dontSupportGroupedRules = isIE && browserVersion < 9;
+            var group = [];
+            var groupItem;
+        }
+    }
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    for (var i=0, length=rules.length; i<length; i++)
+    {
+        // TODO: xxxpedro is there a better way to cache CSS Rules? The problem is that
+        // we cannot add expando properties in the rule object in IE
+        var rid = ssid + ":" + i;
+        var rule = rules[i];
+        var selector = rule.selectorText || "";
+        var lineNo = null;
+
+        // See: Issue 4776: [Firebug lite] CSS Media Types
+        //
+        // Ignore all special selectors like @media and @page
+        if (!selector || selector.indexOf("@") != -1)
+            continue;
+
+        if (isIE)
+            selector = selector.replace(reSelectorTag, function(s){return s.toLowerCase();});
+
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+        // CSS Parser
+        if (shouldParseCSS)
+        {
+            var parsedRule = parsedRules[parsedRulesIndex];
+            var parsedSelector = parsedRule.selector;
+
+            if (dontSupportGroupedRules && parsedSelector.indexOf(",") != -1 && group.length == 0)
+                group = parsedSelector.split(",");
+
+            if (dontSupportGroupedRules && group.length > 0)
+            {
+                groupItem = group.shift();
+
+                if (CssParser.normalizeSelector(selector) == groupItem)
+                    lineNo = parsedRule.line;
+
+                if (group.length == 0)
+                    parsedRulesIndex++;
+            }
+            else if (CssParser.normalizeSelector(selector) == parsedRule.selector)
+            {
+                lineNo = parsedRule.line;
+                parsedRulesIndex++;
+            }
+        }
+        // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+        CSSRuleMap[rid] =
+        {
+            styleSheetId: ssid,
+            styleSheetIndex: i,
+            order: ++globalCSSRuleIndex,
+            specificity:
+                // See: Issue 4777: [Firebug lite] Specificity of CSS Rules
+                //
+                // if it is a normal selector then calculate the specificity
+                selector && selector.indexOf(",") == -1 ?
+                getCSSRuleSpecificity(selector) :
+                // See: Issue 3262: [Firebug lite] Specificity of grouped CSS Rules
+                //
+                // if it is a grouped selector, do not calculate the specificity
+                // because the correct value will depend of the matched element.
+                // The proper specificity value for grouped selectors are calculated
+                // via getElementCSSRules(element)
+                0,
+
+            rule: rule,
+            lineNo: lineNo,
+            selector: selector,
+            cssText: rule.style ? rule.style.cssText : rule.cssText ? rule.cssText : ""
+        };
+
+        // TODO: what happens with elements added after this? Need to create a test case.
+        // Maybe we should place this at getElementCSSRules() but it will make the function
+        // a lot more expensive.
+        //
+        // Maybe add a "refresh" button?
+        var elements = Firebug.Selector(selector, doc);
+
+        for (var j=0, elementsLength=elements.length; j<elementsLength; j++)
+        {
+            var element = elements[j];
+            var eid = ElementCache(element);
+
+            if (!ElementCSSRulesMap[eid])
+                ElementCSSRulesMap[eid] = [];
+
+            ElementCSSRulesMap[eid].push(rid);
+        }
+
+        //console.log(selector, elements);
+    }
+};
+
+// ************************************************************************************************
+// External StyleSheet Loader
+
+var loadExternalStylesheet = function(doc, styleSheetIterator, styleSheet)
+{
+    var url = styleSheet.href;
+    styleSheet.firebugIgnore = true;
+
+    var source = Firebug.Lite.Proxy.load(url);
+
+    // TODO: check for null and error responses
+
+    // remove comments
+    //var reMultiComment = /(\/\*([^\*]|\*(?!\/))*\*\/)/g;
+    //source = source.replace(reMultiComment, "");
+
+    // convert relative addresses to absolute ones
+    source = source.replace(/url\(([^\)]+)\)/g, function(a,name){
+
+        var hasDomain = /\w+:\/\/./.test(name);
+
+        if (!hasDomain)
+        {
+            name = name.replace(/^(["'])(.+)\1$/, "$2");
+            var first = name.charAt(0);
+
+            // relative path, based on root
+            if (first == "/")
+            {
+                // TODO: xxxpedro move to lib or Firebug.Lite.something
+                // getURLRoot
+                var m = /^([^:]+:\/{1,3}[^\/]+)/.exec(url);
+
+                return m ?
+                    "url(" + m[1] + name + ")" :
+                    "url(" + name + ")";
+            }
+            // relative path, based on current location
+            else
+            {
+                // TODO: xxxpedro move to lib or Firebug.Lite.something
+                // getURLPath
+                var path = url.replace(/[^\/]+\.[\w\d]+(\?.+|#.+)?$/g, "");
+
+                path = path + name;
+
+                var reBack = /[^\/]+\/\.\.\//;
+                while(reBack.test(path))
+                {
+                    path = path.replace(reBack, "");
+                }
+
+                //console.log("url(" + path + ")");
+
+                return "url(" + path + ")";
+            }
+        }
+
+        // if it is an absolute path, there is nothing to do
+        return a;
+    });
+
+    var oldStyle = styleSheet.ownerNode;
+
+    if (!oldStyle) return;
+
+    if (!oldStyle.parentNode) return;
+
+    var style = createGlobalElement("style");
+    style.setAttribute("charset","utf-8");
+    style.setAttribute("type", "text/css");
+    style.innerHTML = source;
+
+    //debugger;
+    oldStyle.parentNode.insertBefore(style, oldStyle.nextSibling);
+    oldStyle.parentNode.removeChild(oldStyle);
+
+    doc.styleSheets[doc.styleSheets.length-1].externalURL = url;
+
+    console.log(url, "call " + externalStyleSheetURLs.length, source);
+
+    externalStyleSheetURLs.pop();
+
+    if (processAllStyleSheetsTimeout)
+    {
+        clearTimeout(processAllStyleSheetsTimeout);
+    }
+
+    processAllStyleSheetsTimeout = setTimeout(function(){
+        console.log("processing");
+        FBL.processAllStyleSheets(doc, styleSheetIterator);
+        processAllStyleSheetsTimeout = null;
+    },200);
+
+};
+
+//************************************************************************************************
+// getElementCSSRules
+
+var getElementCSSRules = function(element)
+{
+    var eid = ElementCache(element);
+    var rules = ElementCSSRulesMap[eid];
+
+    if (!rules) return;
+
+    var arr = [element];
+    var Selector = Firebug.Selector;
+    var ruleId, rule;
+
+    // for the case of grouped selectors, we need to calculate the highest
+    // specificity within the selectors of the group that matches the element,
+    // so we can sort the rules properly without over estimating the specificity
+    // of grouped selectors
+    for (var i = 0, length = rules.length; i < length; i++)
+    {
+        ruleId = rules[i];
+        rule = CSSRuleMap[ruleId];
+
+        // check if it is a grouped selector
+        if (rule.selector.indexOf(",") != -1)
+        {
+            var selectors = rule.selector.split(",");
+            var maxSpecificity = -1;
+            var sel, spec, mostSpecificSelector;
+
+            // loop over all selectors in the group
+            for (var j, len = selectors.length; j < len; j++)
+            {
+                sel = selectors[j];
+
+                // find if the selector matches the element
+                if (Selector.matches(sel, arr).length == 1)
+                {
+                    spec = getCSSRuleSpecificity(sel);
+
+                    // find the most specific selector that macthes the element
+                    if (spec > maxSpecificity)
+                    {
+                        maxSpecificity = spec;
+                        mostSpecificSelector = sel;
+                    }
+                }
+            }
+
+            rule.specificity = maxSpecificity;
+        }
+    }
+
+    rules.sort(sortElementRules);
+    //rules.sort(solveRulesTied);
+
+    return rules;
+};
+
+// ************************************************************************************************
+// Rule Specificity
+
+var sortElementRules = function(a, b)
+{
+    var ruleA = CSSRuleMap[a];
+    var ruleB = CSSRuleMap[b];
+
+    var specificityA = ruleA.specificity;
+    var specificityB = ruleB.specificity;
+
+    if (specificityA > specificityB)
+        return 1;
+
+    else if (specificityA < specificityB)
+        return -1;
+
+    else
+        return ruleA.order > ruleB.order ? 1 : -1;
+};
+
+var solveRulesTied = function(a, b)
+{
+    var ruleA = CSSRuleMap[a];
+    var ruleB = CSSRuleMap[b];
+
+    if (ruleA.specificity == ruleB.specificity)
+        return ruleA.order > ruleB.order ? 1 : -1;
+
+    return null;
+};
+
+var getCSSRuleSpecificity = function(selector)
+{
+    var match = selector.match(reSelectorTag);
+    var tagCount = match ? match.length : 0;
+
+    match = selector.match(reSelectorClass);
+    var classCount = match ? match.length : 0;
+
+    match = selector.match(reSelectorId);
+    var idCount = match ? match.length : 0;
+
+    return tagCount + 10*classCount + 100*idCount;
+};
+
+// ************************************************************************************************
+// StyleSheet data
+
+var extractSourceData = function(href)
+{
+    var sourceData =
+    {
+        source: null,
+        startLine: 0
+    };
+
+    if (href)
+    {
+        sourceData.source = Firebug.Lite.Proxy.load(href);
+    }
+    else
+    {
+        // TODO: create extractInternalSourceData(index)
+        // TODO: pre process the position of the inline styles so this will happen only once
+        // in case of having multiple inline styles
+        var index = 0;
+        var ssIndex = ++internalStyleSheetIndex;
+        var reStyleTag = /\<\s*style.*\>/gi;
+        var reEndStyleTag = /\<\/\s*style.*\>/gi;
+
+        var source = Firebug.Lite.Proxy.load(Env.browser.location.href);
+        source = source.replace(/\n\r|\r\n/g, "\n"); // normalize line breaks
+
+        var startLine = 0;
+
+        do
+        {
+            var matchStyleTag = source.match(reStyleTag);
+            var i0 = source.indexOf(matchStyleTag[0]) + matchStyleTag[0].length;
+
+            for (var i=0; i < i0; i++)
+            {
+                if (source.charAt(i) == "\n")
+                    startLine++;
+            }
+
+            source = source.substr(i0);
+
+            index++;
+        }
+        while (index <= ssIndex);
+
+        var matchEndStyleTag = source.match(reEndStyleTag);
+        var i1 = source.indexOf(matchEndStyleTag[0]);
+
+        var extractedSource = source.substr(0, i1);
+
+        sourceData.source = extractedSource;
+        sourceData.startLine = startLine;
+    }
+
+    return sourceData;
+};
+
+// ************************************************************************************************
+// Registration
+
+FBL.CssAnalyzer = CssAnalyzer;
+
+// ************************************************************************************************
+}});
+
+
+/* See license.txt for terms of usage */
+
+// move to FBL
+(function() {
+
+// ************************************************************************************************
+// XPath
+
+/**
+ * Gets an XPath for an element which describes its hierarchical location.
+ */
+this.getElementXPath = function(element)
+{
+    try
+    {
+        if (element && element.id)
+            return '//*[@id="' + element.id + '"]';
+        else
+            return this.getElementTreeXPath(element);
+    }
+    catch(E)
+    {
+        // xxxpedro: trying to detect the mysterious error:
+        // Security error" code: "1000
+        //debugger;
+    }
+};
+
+this.getElementTreeXPath = function(element)
+{
+    var paths = [];
+
+    for (; element && element.nodeType == 1; element = element.parentNode)
+    {
+        var index = 0;
+        var nodeName = element.nodeName;
+
+        for (var sibling = element.previousSibling; sibling; sibling = sibling.previousSibling)
+        {
+            if (sibling.nodeType != 1) continue;
+
+            if (sibling.nodeName == nodeName)
+                ++index;
+        }
+
+        var tagName = element.nodeName.toLowerCase();
+        var pathIndex = (index ? "[" + (index+1) + "]" : "");
+        paths.splice(0, 0, tagName + pathIndex);
+    }
+
+    return paths.length ? "/" + paths.join("/") : null;
+};
+
+this.getElementsByXPath = function(doc, xpath)
+{
+    var nodes = [];
+
+    try {
+        var result = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
+        for (var item = result.iterateNext(); item; item = result.iterateNext())
+            nodes.push(item);
+    }
+    catch (exc)
+    {
+        // Invalid xpath expressions make their way here sometimes.  If that happens,
+        // we still want to return an empty set without an exception.
+    }
+
+    return nodes;
+};
+
+this.getRuleMatchingElements = function(rule, doc)
+{
+    var css = rule.selectorText;
+    var xpath = this.cssToXPath(css);
+    return this.getElementsByXPath(doc, xpath);
+};
+
+
+}).call(FBL);
+
+
+
+
+FBL.ns(function() { with (FBL) {
+
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+
+var toCamelCase = function toCamelCase(s)
+{
+    return s.replace(reSelectorCase, toCamelCaseReplaceFn);
+};
+
+var toSelectorCase = function toSelectorCase(s)
+{
+  return s.replace(reCamelCase, "-$1").toLowerCase();
+
+};
+
+var reCamelCase = /([A-Z])/g;
+var reSelectorCase = /\-(.)/g;
+var toCamelCaseReplaceFn = function toCamelCaseReplaceFn(m,g)
+{
+    return g.toUpperCase();
+};
+
+// ************************************************************************************************
+
+var ElementCache = Firebug.Lite.Cache.Element;
+var StyleSheetCache = Firebug.Lite.Cache.StyleSheet;
+
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+// ************************************************************************************************
+
+
+// ************************************************************************************************
+// Constants
+
+//const Cc = Components.classes;
+//const Ci = Components.interfaces;
+//const nsIDOMCSSStyleRule = Ci.nsIDOMCSSStyleRule;
+//const nsIInterfaceRequestor = Ci.nsIInterfaceRequestor;
+//const nsISelectionDisplay = Ci.nsISelectionDisplay;
+//const nsISelectionController = Ci.nsISelectionController;
+
+// See: http://mxr.mozilla.org/mozilla1.9.2/source/content/events/public/nsIEventStateManager.h#153
+//const STATE_ACTIVE  = 0x01;
+//const STATE_FOCUS   = 0x02;
+//const STATE_HOVER   = 0x04;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+Firebug.SourceBoxPanel = Firebug.Panel;
+
+var reSelectorTag = /(^|\s)(?:\w+)/g;
+
+var domUtils = null;
+
+var textContent = isIE ? "innerText" : "textContent";
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var CSSDomplateBase = {
+    isEditable: function(rule)
+    {
+        return !rule.isSystemSheet;
+    },
+    isSelectorEditable: function(rule)
+    {
+        return rule.isSelectorEditable && this.isEditable(rule);
+    }
+};
+
+var CSSPropTag = domplate(CSSDomplateBase, {
+    tag: DIV({"class": "cssProp focusRow", $disabledStyle: "$prop.disabled",
+          $editGroup: "$rule|isEditable",
+          $cssOverridden: "$prop.overridden", role : "option"},
+        A({"class": "cssPropDisable"}, "&nbsp;&nbsp;"),
+        SPAN({"class": "cssPropName", $editable: "$rule|isEditable"}, "$prop.name"),
+        SPAN({"class": "cssColon"}, ":"),
+        SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"}, "$prop.value$prop.important"),
+        SPAN({"class": "cssSemi"}, ";")
+    )
+});
+
+var CSSRuleTag =
+    TAG("$rule.tag", {rule: "$rule"});
+
+var CSSImportRuleTag = domplate({
+    tag: DIV({"class": "cssRule insertInto focusRow importRule", _repObject: "$rule.rule"},
+        "@import &quot;",
+        A({"class": "objectLink", _repObject: "$rule.rule.styleSheet"}, "$rule.rule.href"),
+        "&quot;;"
+    )
+});
+
+var CSSStyleRuleTag = domplate(CSSDomplateBase, {
+    tag: DIV({"class": "cssRule insertInto",
+            $cssEditableRule: "$rule|isEditable",
+            $editGroup: "$rule|isSelectorEditable",
+            _repObject: "$rule.rule",
+            "ruleId": "$rule.id", role : 'presentation'},
+        DIV({"class": "cssHead focusRow", role : 'listitem'},
+            SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"}, "$rule.selector"), " {"
+        ),
+        DIV({role : 'group'},
+            DIV({"class": "cssPropertyListBox", role : 'listbox'},
+                FOR("prop", "$rule.props",
+                    TAG(CSSPropTag.tag, {rule: "$rule", prop: "$prop"})
+                )
+            )
+        ),
+        DIV({"class": "editable insertBefore", role:"presentation"}, "}")
+    )
+});
+
+var reSplitCSS =  /(url\("?[^"\)]+?"?\))|(rgb\(.*?\))|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,2})?)|([^,\s]+)|"(.*?)"/;
+
+var reURL = /url\("?([^"\)]+)?"?\)/;
+
+var reRepeat = /no-repeat|repeat-x|repeat-y|repeat/;
+
+//const sothinkInstalled = !!$("swfcatcherKey_sidebar");
+var sothinkInstalled = false;
+var styleGroups =
+{
+    text: [
+        "font-family",
+        "font-size",
+        "font-weight",
+        "font-style",
+        "color",
+        "text-transform",
+        "text-decoration",
+        "letter-spacing",
+        "word-spacing",
+        "line-height",
+        "text-align",
+        "vertical-align",
+        "direction",
+        "column-count",
+        "column-gap",
+        "column-width"
+    ],
+
+    background: [
+        "background-color",
+        "background-image",
+        "background-repeat",
+        "background-position",
+        "background-attachment",
+        "opacity"
+    ],
+
+    box: [
+        "width",
+        "height",
+        "top",
+        "right",
+        "bottom",
+        "left",
+        "margin-top",
+        "margin-right",
+        "margin-bottom",
+        "margin-left",
+        "padding-top",
+        "padding-right",
+        "padding-bottom",
+        "padding-left",
+        "border-top-width",
+        "border-right-width",
+        "border-bottom-width",
+        "border-left-width",
+        "border-top-color",
+        "border-right-color",
+        "border-bottom-color",
+        "border-left-color",
+        "border-top-style",
+        "border-right-style",
+        "border-bottom-style",
+        "border-left-style",
+        "-moz-border-top-radius",
+        "-moz-border-right-radius",
+        "-moz-border-bottom-radius",
+        "-moz-border-left-radius",
+        "outline-top-width",
+        "outline-right-width",
+        "outline-bottom-width",
+        "outline-left-width",
+        "outline-top-color",
+        "outline-right-color",
+        "outline-bottom-color",
+        "outline-left-color",
+        "outline-top-style",
+        "outline-right-style",
+        "outline-bottom-style",
+        "outline-left-style"
+    ],
+
+    layout: [
+        "position",
+        "display",
+        "visibility",
+        "z-index",
+        "overflow-x",  // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow
+        "overflow-y",
+        "overflow-clip",
+        "white-space",
+        "clip",
+        "float",
+        "clear",
+        "-moz-box-sizing"
+    ],
+
+    other: [
+        "cursor",
+        "list-style-image",
+        "list-style-position",
+        "list-style-type",
+        "marker-offset",
+        "user-focus",
+        "user-select",
+        "user-modify",
+        "user-input"
+    ]
+};
+
+var styleGroupTitles =
+{
+    text: "Text",
+    background: "Background",
+    box: "Box Model",
+    layout: "Layout",
+    other: "Other"
+};
+
+Firebug.CSSModule = extend(Firebug.Module,
+{
+    freeEdit: function(styleSheet, value)
+    {
+        if (!styleSheet.editStyleSheet)
+        {
+            var ownerNode = getStyleSheetOwnerNode(styleSheet);
+            styleSheet.disabled = true;
+
+            var url = CCSV("@mozilla.org/network/standard-url;1", Components.interfaces.nsIURL);
+            url.spec = styleSheet.href;
+
+            var editStyleSheet = ownerNode.ownerDocument.createElementNS(
+                "http://www.w3.org/1999/xhtml",
+                "style");
+            unwrapObject(editStyleSheet).firebugIgnore = true;
+            editStyleSheet.setAttribute("type", "text/css");
+            editStyleSheet.setAttributeNS(
+                "http://www.w3.org/XML/1998/namespace",
+                "base",
+                url.directory);
+            if (ownerNode.hasAttribute("media"))
+            {
+              editStyleSheet.setAttribute("media", ownerNode.getAttribute("media"));
+            }
+
+            // Insert the edited stylesheet directly after the old one to ensure the styles
+            // cascade properly.
+            ownerNode.parentNode.insertBefore(editStyleSheet, ownerNode.nextSibling);
+
+            styleSheet.editStyleSheet = editStyleSheet;
+        }
+
+        styleSheet.editStyleSheet.innerHTML = value;
+        if (FBTrace.DBG_CSS)
+            FBTrace.sysout("css.saveEdit styleSheet.href:"+styleSheet.href+" got innerHTML:"+value+"\n");
+
+        dispatch(this.fbListeners, "onCSSFreeEdit", [styleSheet, value]);
+    },
+
+    insertRule: function(styleSheet, cssText, ruleIndex)
+    {
+        if (FBTrace.DBG_CSS) FBTrace.sysout("Insert: " + ruleIndex + " " + cssText);
+        var insertIndex = styleSheet.insertRule(cssText, ruleIndex);
+
+        dispatch(this.fbListeners, "onCSSInsertRule", [styleSheet, cssText, ruleIndex]);
+
+        return insertIndex;
+    },
+
+    deleteRule: function(styleSheet, ruleIndex)
+    {
+        if (FBTrace.DBG_CSS) FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length, styleSheet.cssRules);
+        dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]);
+
+        styleSheet.deleteRule(ruleIndex);
+    },
+
+    setProperty: function(rule, propName, propValue, propPriority)
+    {
+        var style = rule.style || rule;
+
+        // Record the original CSS text for the inline case so we can reconstruct at a later
+        // point for diffing purposes
+        var baseText = style.cssText;
+
+        // good browsers
+        if (style.getPropertyValue)
+        {
+            var prevValue = style.getPropertyValue(propName);
+            var prevPriority = style.getPropertyPriority(propName);
+
+            // XXXjoe Gecko bug workaround: Just changing priority doesn't have any effect
+            // unless we remove the property first
+            style.removeProperty(propName);
+
+            style.setProperty(propName, propValue, propPriority);
+        }
+        // sad browsers
+        else
+        {
+            // TODO: xxxpedro parse CSS rule to find property priority in IE?
+            //console.log(propName, propValue);
+            style[toCamelCase(propName)] = propValue;
+        }
+
+        if (propName) {
+            dispatch(this.fbListeners, "onCSSSetProperty", [style, propName, propValue, propPriority, prevValue, prevPriority, rule, baseText]);
+        }
+    },
+
+    removeProperty: function(rule, propName, parent)
+    {
+        var style = rule.style || rule;
+
+        // Record the original CSS text for the inline case so we can reconstruct at a later
+        // point for diffing purposes
+        var baseText = style.cssText;
+
+        if (style.getPropertyValue)
+        {
+
+            var prevValue = style.getPropertyValue(propName);
+            var prevPriority = style.getPropertyPriority(propName);
+
+            style.removeProperty(propName);
+        }
+        else
+        {
+            style[toCamelCase(propName)] = "";
+        }
+
+        if (propName) {
+            dispatch(this.fbListeners, "onCSSRemoveProperty", [style, propName, prevValue, prevPriority, rule, baseText]);
+        }
+    }/*,
+
+    cleanupSheets: function(doc, context)
+    {
+        // Due to the manner in which the layout engine handles multiple
+        // references to the same sheet we need to kick it a little bit.
+        // The injecting a simple stylesheet then removing it will force
+        // Firefox to regenerate it's CSS hierarchy.
+        //
+        // WARN: This behavior was determined anecdotally.
+        // See http://code.google.com/p/fbug/issues/detail?id=2440
+        var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
+        style.setAttribute("charset","utf-8");
+        unwrapObject(style).firebugIgnore = true;
+        style.setAttribute("type", "text/css");
+        style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}";
+        addStyleSheet(doc, style);
+        style.parentNode.removeChild(style);
+
+        // https://bugzilla.mozilla.org/show_bug.cgi?id=500365
+        // This voodoo touches each style sheet to force some Firefox internal change to allow edits.
+        var styleSheets = getAllStyleSheets(context);
+        for(var i = 0; i < styleSheets.length; i++)
+        {
+            try
+            {
+                var rules = styleSheets[i].cssRules;
+                if (rules.length > 0)
+                    var touch = rules[0];
+                if (FBTrace.DBG_CSS && touch)
+                    FBTrace.sysout("css.show() touch "+typeof(touch)+" in "+(styleSheets[i].href?styleSheets[i].href:context.getName()));
+            }
+            catch(e)
+            {
+                if (FBTrace.DBG_ERRORS)
+                    FBTrace.sysout("css.show: sheet.cssRules FAILS for "+(styleSheets[i]?styleSheets[i].href:"null sheet")+e, e);
+            }
+        }
+    },
+    cleanupSheetHandler: function(event, context)
+    {
+        var target = event.target || event.srcElement,
+            tagName = (target.tagName || "").toLowerCase();
+        if (tagName == "link")
+        {
+            this.cleanupSheets(target.ownerDocument, context);
+        }
+    },
+    watchWindow: function(context, win)
+    {
+        var cleanupSheets = bind(this.cleanupSheets, this),
+            cleanupSheetHandler = bind(this.cleanupSheetHandler, this, context),
+            doc = win.document;
+
+        //doc.addEventListener("DOMAttrModified", cleanupSheetHandler, false);
+        //doc.addEventListener("DOMNodeInserted", cleanupSheetHandler, false);
+    },
+    loadedContext: function(context)
+    {
+        var self = this;
+        iterateWindows(context.browser.contentWindow, function(subwin)
+        {
+            self.cleanupSheets(subwin.document, context);
+        });
+    }
+    /**/
+});
+
+// ************************************************************************************************
+
+Firebug.CSSStyleSheetPanel = function() {};
+
+Firebug.CSSStyleSheetPanel.prototype = extend(Firebug.SourceBoxPanel,
+{
+    template: domplate(
+    {
+        tag:
+            DIV({"class": "cssSheet insertInto a11yCSSView"},
+                FOR("rule", "$rules",
+                    CSSRuleTag
+                ),
+                DIV({"class": "cssSheet editable insertBefore"}, "")
+                )
+    }),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    refresh: function()
+    {
+        if (this.location)
+            this.updateLocation(this.location);
+        else if (this.selection)
+            this.updateSelection(this.selection);
+    },
+
+    toggleEditing: function()
+    {
+        if (!this.stylesheetEditor)
+            this.stylesheetEditor = new StyleSheetEditor(this.document);
+
+        if (this.editing)
+            Firebug.Editor.stopEditing();
+        else
+        {
+            if (!this.location)
+                return;
+
+            var styleSheet = this.location.editStyleSheet
+                ? this.location.editStyleSheet.sheet
+                : this.location;
+
+            var css = getStyleSheetCSS(styleSheet, this.context);
+            //var topmost = getTopmostRuleLine(this.panelNode);
+
+            this.stylesheetEditor.styleSheet = this.location;
+            Firebug.Editor.startEditing(this.panelNode, css, this.stylesheetEditor);
+            //this.stylesheetEditor.scrollToLine(topmost.line, topmost.offset);
+        }
+    },
+
+    getStylesheetURL: function(rule)
+    {
+        if (this.location.href)
+            return this.location.href;
+        else
+            return this.context.window.location.href;
+    },
+
+    getRuleByLine: function(styleSheet, line)
+    {
+        if (!domUtils)
+            return null;
+
+        var cssRules = styleSheet.cssRules;
+        for (var i = 0; i < cssRules.length; ++i)
+        {
+            var rule = cssRules[i];
+            if (rule instanceof CSSStyleRule)
+            {
+                var ruleLine = domUtils.getRuleLine(rule);
+                if (ruleLine >= line)
+                    return rule;
+            }
+        }
+    },
+
+    highlightRule: function(rule)
+    {
+        var ruleElement = Firebug.getElementByRepObject(this.panelNode.firstChild, rule);
+        if (ruleElement)
+        {
+            scrollIntoCenterView(ruleElement, this.panelNode);
+            setClassTimed(ruleElement, "jumpHighlight", this.context);
+        }
+    },
+
+    getStyleSheetRules: function(context, styleSheet)
+    {
+        var isSystemSheet = isSystemStyleSheet(styleSheet);
+
+        function appendRules(cssRules)
+        {
+            for (var i = 0; i < cssRules.length; ++i)
+            {
+                var rule = cssRules[i];
+
+                // TODO: xxxpedro opera instanceof stylesheet remove the following comments when
+                // the issue with opera and style sheet Classes has been solved.
+
+                //if (rule instanceof CSSStyleRule)
+                if (instanceOf(rule, "CSSStyleRule"))
+                {
+                    var props = this.getRuleProperties(context, rule);
+                    //var line = domUtils.getRuleLine(rule);
+                    var line = null;
+
+                    var selector = rule.selectorText;
+
+                    if (isIE)
+                    {
+                        selector = selector.replace(reSelectorTag,
+                                function(s){return s.toLowerCase();});
+                    }
+
+                    var ruleId = rule.selectorText+"/"+line;
+                    rules.push({tag: CSSStyleRuleTag.tag, rule: rule, id: ruleId,
+                                selector: selector, props: props,
+                                isSystemSheet: isSystemSheet,
+                                isSelectorEditable: true});
+                }
+                //else if (rule instanceof CSSImportRule)
+                else if (instanceOf(rule, "CSSImportRule"))
+                    rules.push({tag: CSSImportRuleTag.tag, rule: rule});
+                //else if (rule instanceof CSSMediaRule)
+                else if (instanceOf(rule, "CSSMediaRule"))
+                    appendRules.apply(this, [rule.cssRules]);
+                else
+                {
+                    if (FBTrace.DBG_ERRORS || FBTrace.DBG_CSS)
+                        FBTrace.sysout("css getStyleSheetRules failed to classify a rule ", rule);
+                }
+            }
+        }
+
+        var rules = [];
+        appendRules.apply(this, [styleSheet.cssRules || styleSheet.rules]);
+        return rules;
+    },
+
+    parseCSSProps: function(style, inheritMode)
+    {
+        var props = [];
+
+        if (Firebug.expandShorthandProps)
+        {
+            var count = style.length-1,
+                index = style.length;
+            while (index--)
+            {
+                var propName = style.item(count - index);
+                this.addProperty(propName, style.getPropertyValue(propName), !!style.getPropertyPriority(propName), false, inheritMode, props);
+            }
+        }
+        else
+        {
+            var lines = style.cssText.match(/(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g);
+            var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(! important)?;?$/;
+            var line,i=0;
+            // TODO: xxxpedro port to firebug: variable leaked into global namespace
+            var m;
+
+            while(line=lines[i++]){
+                m = propRE.exec(line);
+                if(!m)
+                    continue;
+                //var name = m[1], value = m[2], important = !!m[3];
+                if (m[2])
+                    this.addProperty(m[1], m[2], !!m[3], false, inheritMode, props);
+            };
+        }
+
+        return props;
+    },
+
+    getRuleProperties: function(context, rule, inheritMode)
+    {
+        var props = this.parseCSSProps(rule.style, inheritMode);
+
+        // TODO: xxxpedro port to firebug: variable leaked into global namespace
+        //var line = domUtils.getRuleLine(rule);
+        var line;
+        var ruleId = rule.selectorText+"/"+line;
+        this.addOldProperties(context, ruleId, inheritMode, props);
+        sortProperties(props);
+
+        return props;
+    },
+
+    addOldProperties: function(context, ruleId, inheritMode, props)
+    {
+        if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) )
+        {
+            var moreProps = context.selectorMap[ruleId];
+            for (var i = 0; i < moreProps.length; ++i)
+            {
+                var prop = moreProps[i];
+                this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props);
+            }
+        }
+    },
+
+    addProperty: function(name, value, important, disabled, inheritMode, props)
+    {
+        name = name.toLowerCase();
+
+        if (inheritMode && !inheritedStyleNames[name])
+            return;
+
+        name = this.translateName(name, value);
+        if (name)
+        {
+            value = stripUnits(rgbToHex(value));
+            important = important ? " !important" : "";
+
+            var prop = {name: name, value: value, important: important, disabled: disabled};
+            props.push(prop);
+        }
+    },
+
+    translateName: function(name, value)
+    {
+        // Don't show these proprietary Mozilla properties
+        if ((value == "-moz-initial"
+            && (name == "-moz-background-clip" || name == "-moz-background-origin"
+                || name == "-moz-background-inline-policy"))
+        || (value == "physical"
+            && (name == "margin-left-ltr-source" || name == "margin-left-rtl-source"
+                || name == "margin-right-ltr-source" || name == "margin-right-rtl-source"))
+        || (value == "physical"
+            && (name == "padding-left-ltr-source" || name == "padding-left-rtl-source"
+                || name == "padding-right-ltr-source" || name == "padding-right-rtl-source")))
+            return null;
+
+        // Translate these back to the form the user probably expects
+        if (name == "margin-left-value")
+            return "margin-left";
+        else if (name == "margin-right-value")
+            return "margin-right";
+        else if (name == "margin-top-value")
+            return "margin-top";
+        else if (name == "margin-bottom-value")
+            return "margin-bottom";
+        else if (name == "padding-left-value")
+            return "padding-left";
+        else if (name == "padding-right-value")
+            return "padding-right";
+        else if (name == "padding-top-value")
+            return "padding-top";
+        else if (name == "padding-bottom-value")
+            return "padding-bottom";
+        // XXXjoe What about border!
+        else
+            return name;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    editElementStyle: function()
+    {
+        ///var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0];
+        var rulesBox = $$(".cssElementRuleContainer", this.panelNode)[0];
+        var styleRuleBox = rulesBox && Firebug.getElementByRepObject(rulesBox, this.selection);
+        if (!styleRuleBox)
+        {
+            var rule = {rule: this.selection, inherited: false, selector: "element.style", props: []};
+            if (!rulesBox)
+            {
+                // The element did not have any displayed styles. We need to create the whole tree and remove
+                // the no styles message
+                styleRuleBox = this.template.cascadedTag.replace({
+                    rules: [rule], inherited: [], inheritLabel: "Inherited from" // $STR("InheritedFrom")
+                }, this.panelNode);
+
+                ///styleRuleBox = styleRuleBox.getElementsByClassName("cssElementRuleContainer")[0];
+                styleRuleBox = $$(".cssElementRuleContainer", styleRuleBox)[0];
+            }
+            else
+                styleRuleBox = this.template.ruleTag.insertBefore({rule: rule}, rulesBox);
+
+            ///styleRuleBox = styleRuleBox.getElementsByClassName("insertInto")[0];
+            styleRuleBox = $$(".insertInto", styleRuleBox)[0];
+        }
+
+        Firebug.Editor.insertRowForObject(styleRuleBox);
+    },
+
+    insertPropertyRow: function(row)
+    {
+        Firebug.Editor.insertRowForObject(row);
+    },
+
+    insertRule: function(row)
+    {
+        var location = getAncestorByClass(row, "cssRule");
+        if (!location)
+        {
+            location = getChildByClass(this.panelNode, "cssSheet");
+            Firebug.Editor.insertRowForObject(location);
+        }
+        else
+        {
+            Firebug.Editor.insertRow(location, "before");
+        }
+    },
+
+    editPropertyRow: function(row)
+    {
+        var propValueBox = getChildByClass(row, "cssPropValue");
+        Firebug.Editor.startEditing(propValueBox);
+    },
+
+    deletePropertyRow: function(row)
+    {
+        var rule = Firebug.getRepObject(row);
+        var propName = getChildByClass(row, "cssPropName")[textContent];
+        Firebug.CSSModule.removeProperty(rule, propName);
+
+        // Remove the property from the selector map, if it was disabled
+        var ruleId = Firebug.getRepNode(row).getAttribute("ruleId");
+        if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) )
+        {
+            var map = this.context.selectorMap[ruleId];
+            for (var i = 0; i < map.length; ++i)
+            {
+                if (map[i].name == propName)
+                {
+                    map.splice(i, 1);
+                    break;
+                }
+            }
+        }
+        if (this.name == "stylesheet")
+            dispatch([Firebug.A11yModel], 'onInlineEditorClose', [this, row.firstChild, true]);
+        row.parentNode.removeChild(row);
+
+        this.markChange(this.name == "stylesheet");
+    },
+
+    disablePropertyRow: function(row)
+    {
+        toggleClass(row, "disabledStyle");
+
+        var rule = Firebug.getRepObject(row);
+        var propName = getChildByClass(row, "cssPropName")[textContent];
+
+        if (!this.context.selectorMap)
+            this.context.selectorMap = {};
+
+        // XXXjoe Generate unique key for elements too
+        var ruleId = Firebug.getRepNode(row).getAttribute("ruleId");
+        if (!(this.context.selectorMap.hasOwnProperty(ruleId)))
+            this.context.selectorMap[ruleId] = [];
+
+        var map = this.context.selectorMap[ruleId];
+        var propValue = getChildByClass(row, "cssPropValue")[textContent];
+        var parsedValue = parsePriority(propValue);
+        if (hasClass(row, "disabledStyle"))
+        {
+            Firebug.CSSModule.removeProperty(rule, propName);
+
+            map.push({"name": propName, "value": parsedValue.value,
+                "important": parsedValue.priority});
+        }
+        else
+        {
+            Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority);
+
+            var index = findPropByName(map, propName);
+            map.splice(index, 1);
+        }
+
+        this.markChange(this.name == "stylesheet");
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onMouseDown: function(event)
+    {
+        //console.log("onMouseDown", event.target || event.srcElement, event);
+
+        // xxxpedro adjusting coordinates because the panel isn't a window yet
+        var offset = event.clientX - this.panelNode.parentNode.offsetLeft;
+
+        // XXjoe Hack to only allow clicking on the checkbox
+        if (!isLeftClick(event) || offset > 20)
+            return;
+
+        var target = event.target || event.srcElement;
+        if (hasClass(target, "textEditor"))
+            return;
+
+        var row = getAncestorByClass(target, "cssProp");
+        if (row && hasClass(row, "editGroup"))
+        {
+            this.disablePropertyRow(row);
+            cancelEvent(event);
+        }
+    },
+
+    onDoubleClick: function(event)
+    {
+        //console.log("onDoubleClick", event.target || event.srcElement, event);
+
+        // xxxpedro adjusting coordinates because the panel isn't a window yet
+        var offset = event.clientX - this.panelNode.parentNode.offsetLeft;
+
+        if (!isLeftClick(event) || offset <= 20)
+            return;
+
+        var target = event.target || event.srcElement;
+
+        //console.log("ok", target, hasClass(target, "textEditorInner"), !isLeftClick(event), offset <= 20);
+
+        // if the inline editor was clicked, don't insert a new rule
+        if (hasClass(target, "textEditorInner"))
+            return;
+
+        var row = getAncestorByClass(target, "cssRule");
+        if (row && !getAncestorByClass(target, "cssPropName")
+            && !getAncestorByClass(target, "cssPropValue"))
+        {
+            this.insertPropertyRow(row);
+            cancelEvent(event);
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    name: "stylesheet",
+    title: "CSS",
+    parentPanel: null,
+    searchable: true,
+    dependents: ["css", "stylesheet", "dom", "domSide", "layout"],
+
+    options:
+    {
+        hasToolButtons: true
+    },
+
+    create: function()
+    {
+        Firebug.Panel.create.apply(this, arguments);
+
+        this.onMouseDown = bind(this.onMouseDown, this);
+        this.onDoubleClick = bind(this.onDoubleClick, this);
+
+        if (this.name == "stylesheet")
+        {
+            this.onChangeSelect = bind(this.onChangeSelect, this);
+
+            var doc = Firebug.browser.document;
+            var selectNode = this.selectNode = createElement("select");
+
+            CssAnalyzer.processAllStyleSheets(doc, function(doc, styleSheet)
+            {
+                var key = StyleSheetCache.key(styleSheet);
+                var fileName = getFileName(styleSheet.href) || getFileName(doc.location.href);
+                var option = createElement("option", {value: key});
+
+                option.appendChild(Firebug.chrome.document.createTextNode(fileName));
+                selectNode.appendChild(option);
+            });
+
+            this.toolButtonsNode.appendChild(selectNode);
+        }
+        /**/
+    },
+
+    onChangeSelect: function(event)
+    {
+        event = event || window.event;
+        var target = event.srcElement || event.currentTarget;
+        var key = target.value;
+        var styleSheet = StyleSheetCache.get(key);
+
+        this.updateLocation(styleSheet);
+    },
+
+    initialize: function()
+    {
+        Firebug.Panel.initialize.apply(this, arguments);
+
+        //if (!domUtils)
+        //{
+        //    try {
+        //        domUtils = CCSV("@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
+        //    } catch (exc) {
+        //        if (FBTrace.DBG_ERRORS)
+        //            FBTrace.sysout("@mozilla.org/inspector/dom-utils;1 FAILED to load: "+exc, exc);
+        //    }
+        //}
+
+        //TODO: xxxpedro
+        this.context = Firebug.chrome; // TODO: xxxpedro css2
+        this.document = Firebug.chrome.document; // TODO: xxxpedro css2
+
+        this.initializeNode();
+
+        if (this.name == "stylesheet")
+        {
+            var styleSheets = Firebug.browser.document.styleSheets;
+
+            if (styleSheets.length > 0)
+            {
+                addEvent(this.selectNode, "change", this.onChangeSelect);
+
+                this.updateLocation(styleSheets[0]);
+            }
+        }
+
+        //Firebug.SourceBoxPanel.initialize.apply(this, arguments);
+    },
+
+    shutdown: function()
+    {
+        // must destroy the editor when we leave the panel to avoid problems (Issue 2981)
+        Firebug.Editor.stopEditing();
+
+        if (this.name == "stylesheet")
+        {
+            removeEvent(this.selectNode, "change", this.onChangeSelect);
+        }
+
+        this.destroyNode();
+
+        Firebug.Panel.shutdown.apply(this, arguments);
+    },
+
+    destroy: function(state)
+    {
+        //state.scrollTop = this.panelNode.scrollTop ? this.panelNode.scrollTop : this.lastScrollTop;
+
+        //persistObjects(this, state);
+
+        // xxxpedro we are stopping the editor in the shutdown method already
+        //Firebug.Editor.stopEditing();
+        Firebug.Panel.destroy.apply(this, arguments);
+    },
+
+    initializeNode: function(oldPanelNode)
+    {
+        addEvent(this.panelNode, "mousedown", this.onMouseDown);
+        addEvent(this.panelNode, "dblclick", this.onDoubleClick);
+        //Firebug.SourceBoxPanel.initializeNode.apply(this, arguments);
+        //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'css']);
+    },
+
+    destroyNode: function()
+    {
+        removeEvent(this.panelNode, "mousedown", this.onMouseDown);
+        removeEvent(this.panelNode, "dblclick", this.onDoubleClick);
+        //Firebug.SourceBoxPanel.destroyNode.apply(this, arguments);
+        //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'css']);
+    },
+
+    ishow: function(state)
+    {
+        Firebug.Inspector.stopInspecting(true);
+
+        this.showToolbarButtons("fbCSSButtons", true);
+
+        if (this.context.loaded && !this.location) // wait for loadedContext to restore the panel
+        {
+            restoreObjects(this, state);
+
+            if (!this.location)
+                this.location = this.getDefaultLocation();
+
+            if (state && state.scrollTop)
+                this.panelNode.scrollTop = state.scrollTop;
+        }
+    },
+
+    ihide: function()
+    {
+        this.showToolbarButtons("fbCSSButtons", false);
+
+        this.lastScrollTop = this.panelNode.scrollTop;
+    },
+
+    supportsObject: function(object)
+    {
+        if (object instanceof CSSStyleSheet)
+            return 1;
+        else if (object instanceof CSSStyleRule)
+            return 2;
+        else if (object instanceof CSSStyleDeclaration)
+            return 2;
+        else if (object instanceof SourceLink && object.type == "css" && reCSS.test(object.href))
+            return 2;
+        else
+            return 0;
+    },
+
+    updateLocation: function(styleSheet)
+    {
+        if (!styleSheet)
+            return;
+        if (styleSheet.editStyleSheet)
+            styleSheet = styleSheet.editStyleSheet.sheet;
+
+        // if it is a restricted stylesheet, show the warning message and abort the update process
+        if (styleSheet.restricted)
+        {
+            FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, this.panelNode);
+
+            // TODO: xxxpedro remove when there the external resource problem is fixed
+            CssAnalyzer.externalStyleSheetWarning.tag.append({
+                object: "The stylesheet could not be loaded due to access restrictions. ",
+                link: "more...",
+                href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22Access_to_restricted_URI_denied.22"
+            }, this.panelNode);
+
+            return;
+        }
+
+        var rules = this.getStyleSheetRules(this.context, styleSheet);
+
+        var result;
+        if (rules.length)
+            // FIXME xxxpedro chromenew this is making iPad's Safari to crash
+            result = this.template.tag.replace({rules: rules}, this.panelNode);
+        else
+            result = FirebugReps.Warning.tag.replace({object: "EmptyStyleSheet"}, this.panelNode);
+
+        // TODO: xxxpedro need to fix showToolbarButtons function
+        //this.showToolbarButtons("fbCSSButtons", !isSystemStyleSheet(this.location));
+
+        //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, this.panelNode]);
+    },
+
+    updateSelection: function(object)
+    {
+        this.selection = null;
+
+        if (object instanceof CSSStyleDeclaration) {
+            object = object.parentRule;
+        }
+
+        if (object instanceof CSSStyleRule)
+        {
+            this.navigate(object.parentStyleSheet);
+            this.highlightRule(object);
+        }
+        else if (object instanceof CSSStyleSheet)
+        {
+            this.navigate(object);
+        }
+        else if (object instanceof SourceLink)
+        {
+            try
+            {
+                var sourceLink = object;
+
+                var sourceFile = getSourceFileByHref(sourceLink.href, this.context);
+                if (sourceFile)
+                {
+                    clearNode(this.panelNode);  // replace rendered stylesheets
+                    this.showSourceFile(sourceFile);
+
+                    var lineNo = object.line;
+                    if (lineNo)
+                        this.scrollToLine(lineNo, this.jumpHighlightFactory(lineNo, this.context));
+                }
+                else // XXXjjb we should not be taking this path
+                {
+                    var stylesheet = getStyleSheetByHref(sourceLink.href, this.context);
+                    if (stylesheet)
+                        this.navigate(stylesheet);
+                    else
+                    {
+                        if (FBTrace.DBG_CSS)
+                            FBTrace.sysout("css.updateSelection no sourceFile for "+sourceLink.href, sourceLink);
+                    }
+                }
+            }
+            catch(exc) {
+                if (FBTrace.DBG_CSS)
+                    FBTrace.sysout("css.upDateSelection FAILS "+exc, exc);
+            }
+        }
+    },
+
+    updateOption: function(name, value)
+    {
+        if (name == "expandShorthandProps")
+            this.refresh();
+    },
+
+    getLocationList: function()
+    {
+        var styleSheets = getAllStyleSheets(this.context);
+        return styleSheets;
+    },
+
+    getOptionsMenuItems: function()
+    {
+        return [
+            {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps,
+                    command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") },
+            "-",
+            {label: "Refresh", command: bind(this.refresh, this) }
+        ];
+    },
+
+    getContextMenuItems: function(style, target)
+    {
+        var items = [];
+
+        if (this.infoTipType == "color")
+        {
+            items.push(
+                {label: "CopyColor",
+                    command: bindFixed(copyToClipboard, FBL, this.infoTipObject) }
+            );
+        }
+        else if (this.infoTipType == "image")
+        {
+            items.push(
+                {label: "CopyImageLocation",
+                    command: bindFixed(copyToClipboard, FBL, this.infoTipObject) },
+                {label: "OpenImageInNewTab",
+                    command: bindFixed(openNewTab, FBL, this.infoTipObject) }
+            );
+        }
+
+        ///if (this.selection instanceof Element)
+        if (isElement(this.selection))
+        {
+            items.push(
+                //"-",
+                {label: "EditStyle",
+                    command: bindFixed(this.editElementStyle, this) }
+            );
+        }
+        else if (!isSystemStyleSheet(this.selection))
+        {
+            items.push(
+                    //"-",
+                    {label: "NewRule",
+                        command: bindFixed(this.insertRule, this, target) }
+                );
+        }
+
+        var cssRule = getAncestorByClass(target, "cssRule");
+        if (cssRule && hasClass(cssRule, "cssEditableRule"))
+        {
+            items.push(
+                "-",
+                {label: "NewProp",
+                    command: bindFixed(this.insertPropertyRow, this, target) }
+            );
+
+            var propRow = getAncestorByClass(target, "cssProp");
+            if (propRow)
+            {
+                var propName = getChildByClass(propRow, "cssPropName")[textContent];
+                var isDisabled = hasClass(propRow, "disabledStyle");
+
+                items.push(
+                    {label: $STRF("EditProp", [propName]), nol10n: true,
+                        command: bindFixed(this.editPropertyRow, this, propRow) },
+                    {label: $STRF("DeleteProp", [propName]), nol10n: true,
+                        command: bindFixed(this.deletePropertyRow, this, propRow) },
+                    {label: $STRF("DisableProp", [propName]), nol10n: true,
+                        type: "checkbox", checked: isDisabled,
+                        command: bindFixed(this.disablePropertyRow, this, propRow) }
+                );
+            }
+        }
+
+        items.push(
+            "-",
+            {label: "Refresh", command: bind(this.refresh, this) }
+        );
+
+        return items;
+    },
+
+    browseObject: function(object)
+    {
+        if (this.infoTipType == "image")
+        {
+            openNewTab(this.infoTipObject);
+            return true;
+        }
+    },
+
+    showInfoTip: function(infoTip, target, x, y)
+    {
+        var propValue = getAncestorByClass(target, "cssPropValue");
+        if (propValue)
+        {
+            var offset = getClientOffset(propValue);
+            var offsetX = x-offset.x;
+
+            var text = propValue[textContent];
+            var charWidth = propValue.offsetWidth/text.length;
+            var charOffset = Math.floor(offsetX/charWidth);
+
+            var cssValue = parseCSSValue(text, charOffset);
+            if (cssValue)
+            {
+                if (cssValue.value == this.infoTipValue)
+                    return true;
+
+                this.infoTipValue = cssValue.value;
+
+                if (cssValue.type == "rgb" || (!cssValue.type && isColorKeyword(cssValue.value)))
+                {
+                    this.infoTipType = "color";
+                    this.infoTipObject = cssValue.value;
+
+                    return Firebug.InfoTip.populateColorInfoTip(infoTip, cssValue.value);
+                }
+                else if (cssValue.type == "url")
+                {
+                    ///var propNameNode = target.parentNode.getElementsByClassName("cssPropName").item(0);
+                    var propNameNode = getElementByClass(target.parentNode, "cssPropName");
+                    if (propNameNode && isImageRule(propNameNode[textContent]))
+                    {
+                        var rule = Firebug.getRepObject(target);
+                        var baseURL = this.getStylesheetURL(rule);
+                        var relURL = parseURLValue(cssValue.value);
+                        var absURL = isDataURL(relURL) ? relURL:absoluteURL(relURL, baseURL);
+                        var repeat = parseRepeatValue(text);
+
+                        this.infoTipType = "image";
+                        this.infoTipObject = absURL;
+
+                        return Firebug.InfoTip.populateImageInfoTip(infoTip, absURL, repeat);
+                    }
+                }
+            }
+        }
+
+        delete this.infoTipType;
+        delete this.infoTipValue;
+        delete this.infoTipObject;
+    },
+
+    getEditor: function(target, value)
+    {
+        if (target == this.panelNode
+            || hasClass(target, "cssSelector") || hasClass(target, "cssRule")
+            || hasClass(target, "cssSheet"))
+        {
+            if (!this.ruleEditor)
+                this.ruleEditor = new CSSRuleEditor(this.document);
+
+            return this.ruleEditor;
+        }
+        else
+        {
+            if (!this.editor)
+                this.editor = new CSSEditor(this.document);
+
+            return this.editor;
+        }
+    },
+
+    getDefaultLocation: function()
+    {
+        try
+        {
+            var styleSheets = this.context.window.document.styleSheets;
+            if (styleSheets.length)
+            {
+                var sheet = styleSheets[0];
+                return (Firebug.filterSystemURLs && isSystemURL(getURLForStyleSheet(sheet))) ? null : sheet;
+            }
+        }
+        catch (exc)
+        {
+            if (FBTrace.DBG_LOCATIONS)
+                FBTrace.sysout("css.getDefaultLocation FAILS "+exc, exc);
+        }
+    },
+
+    getObjectDescription: function(styleSheet)
+    {
+        var url = getURLForStyleSheet(styleSheet);
+        var instance = getInstanceForStyleSheet(styleSheet);
+
+        var baseDescription = splitURLBase(url);
+        if (instance) {
+          baseDescription.name = baseDescription.name + " #" + (instance + 1);
+        }
+        return baseDescription;
+    },
+
+    search: function(text, reverse)
+    {
+        var curDoc = this.searchCurrentDoc(!Firebug.searchGlobal, text, reverse);
+        if (!curDoc && Firebug.searchGlobal)
+        {
+            return this.searchOtherDocs(text, reverse);
+        }
+        return curDoc;
+    },
+
+    searchOtherDocs: function(text, reverse)
+    {
+        var scanRE = Firebug.Search.getTestingRegex(text);
+        function scanDoc(styleSheet) {
+            // we don't care about reverse here as we are just looking for existence,
+            // if we do have a result we will handle the reverse logic on display
+            for (var i = 0; i < styleSheet.cssRules.length; i++)
+            {
+                if (scanRE.test(styleSheet.cssRules[i].cssText))
+                {
+                    return true;
+                }
+            }
+        }
+
+        if (this.navigateToNextDocument(scanDoc, reverse))
+        {
+            return this.searchCurrentDoc(true, text, reverse);
+        }
+    },
+
+    searchCurrentDoc: function(wrapSearch, text, reverse)
+    {
+        if (!text)
+        {
+            delete this.currentSearch;
+            return false;
+        }
+
+        var row;
+        if (this.currentSearch && text == this.currentSearch.text)
+        {
+            row = this.currentSearch.findNext(wrapSearch, false, reverse, Firebug.Search.isCaseSensitive(text));
+        }
+        else
+        {
+            if (this.editing)
+            {
+                this.currentSearch = new TextSearch(this.stylesheetEditor.box);
+                row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text));
+
+                if (row)
+                {
+                    var sel = this.document.defaultView.getSelection();
+                    sel.removeAllRanges();
+                    sel.addRange(this.currentSearch.range);
+                    scrollSelectionIntoView(this);
+                    return true;
+                }
+                else
+                    return false;
+            }
+            else
+            {
+                function findRow(node) { return node.nodeType == 1 ? node : node.parentNode; }
+                this.currentSearch = new TextSearch(this.panelNode, findRow);
+                row = this.currentSearch.find(text, reverse, Firebug.Search.isCaseSensitive(text));
+            }
+        }
+
+        if (row)
+        {
+            this.document.defaultView.getSelection().selectAllChildren(row);
+            scrollIntoCenterView(row, this.panelNode);
+            dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, row]);
+            return true;
+        }
+        else
+        {
+            dispatch([Firebug.A11yModel], 'onCSSSearchMatchFound', [this, text, null]);
+            return false;
+        }
+    },
+
+    getSearchOptionsMenuItems: function()
+    {
+        return [
+            Firebug.Search.searchOptionMenu("search.Case_Sensitive", "searchCaseSensitive"),
+            Firebug.Search.searchOptionMenu("search.Multiple_Files", "searchGlobal")
+        ];
+    }
+});
+/**/
+// ************************************************************************************************
+
+function CSSElementPanel() {}
+
+CSSElementPanel.prototype = extend(Firebug.CSSStyleSheetPanel.prototype,
+{
+    template: domplate(
+    {
+        cascadedTag:
+            DIV({"class": "a11yCSSView",  role : 'presentation'},
+                DIV({role : 'list', 'aria-label' : $STR('aria.labels.style rules') },
+                    FOR("rule", "$rules",
+                        TAG("$ruleTag", {rule: "$rule"})
+                    )
+                ),
+                DIV({role : "list", 'aria-label' :$STR('aria.labels.inherited style rules')},
+                    FOR("section", "$inherited",
+                        H1({"class": "cssInheritHeader groupHeader focusRow", role : 'listitem' },
+                            SPAN({"class": "cssInheritLabel"}, "$inheritLabel"),
+                            TAG(FirebugReps.Element.shortTag, {object: "$section.element"})
+                        ),
+                        DIV({role : 'group'},
+                            FOR("rule", "$section.rules",
+                                TAG("$ruleTag", {rule: "$rule"})
+                            )
+                        )
+                    )
+                 )
+            ),
+
+        ruleTag:
+            isIE ?
+            // IE needs the sourceLink first, otherwise it will be rendered outside the panel
+            DIV({"class": "cssElementRuleContainer"},
+                TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"}),
+                TAG(CSSStyleRuleTag.tag, {rule: "$rule"})
+            )
+            :
+            // other browsers need the sourceLink last, otherwise it will cause an extra space
+            // before the rule representation
+            DIV({"class": "cssElementRuleContainer"},
+                TAG(CSSStyleRuleTag.tag, {rule: "$rule"}),
+                TAG(FirebugReps.SourceLink.tag, {object: "$rule.sourceLink"})
+            )
+    }),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    updateCascadeView: function(element)
+    {
+        //dispatch([Firebug.A11yModel], 'onBeforeCSSRulesAdded', [this]);
+        var rules = [], sections = [], usedProps = {};
+        this.getInheritedRules(element, sections, usedProps);
+        this.getElementRules(element, rules, usedProps);
+
+        if (rules.length || sections.length)
+        {
+            var inheritLabel = "Inherited from"; // $STR("InheritedFrom");
+            var result = this.template.cascadedTag.replace({rules: rules, inherited: sections,
+                inheritLabel: inheritLabel}, this.panelNode);
+            //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]);
+        }
+        else
+        {
+            var result = FirebugReps.Warning.tag.replace({object: "EmptyElementCSS"}, this.panelNode);
+            //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]);
+        }
+
+        // TODO: xxxpedro remove when there the external resource problem is fixed
+        if (CssAnalyzer.hasExternalStyleSheet())
+            CssAnalyzer.externalStyleSheetWarning.tag.append({
+                object: "The results here may be inaccurate because some " +
+                        "stylesheets could not be loaded due to access restrictions. ",
+                link: "more...",
+                href: "http://getfirebug.com/wiki/index.php/Firebug_Lite_FAQ#I_keep_seeing_.22This_element_has_no_style_rules.22"
+            }, this.panelNode);
+    },
+
+    getStylesheetURL: function(rule)
+    {
+        // if the parentStyleSheet.href is null, CSS std says its inline style.
+        // TODO: xxxpedro IE doesn't have rule.parentStyleSheet so we must fall back to the doc.location
+        if (rule && rule.parentStyleSheet && rule.parentStyleSheet.href)
+            return rule.parentStyleSheet.href;
+        else
+            return this.selection.ownerDocument.location.href;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getInheritedRules: function(element, sections, usedProps)
+    {
+        var parent = element.parentNode;
+        if (parent && parent.nodeType == 1)
+        {
+            this.getInheritedRules(parent, sections, usedProps);
+
+            var rules = [];
+            this.getElementRules(parent, rules, usedProps, true);
+
+            if (rules.length)
+                sections.splice(0, 0, {element: parent, rules: rules});
+        }
+    },
+
+    getElementRules: function(element, rules, usedProps, inheritMode)
+    {
+        var inspectedRules, displayedRules = {};
+
+        inspectedRules = CssAnalyzer.getElementCSSRules(element);
+
+        if (inspectedRules)
+        {
+            for (var i = 0, length=inspectedRules.length; i < length; ++i)
+            {
+                var ruleId = inspectedRules[i];
+                var ruleData = CssAnalyzer.getRuleData(ruleId);
+                var rule = ruleData.rule;
+
+                var ssid = ruleData.styleSheetId;
+                var parentStyleSheet = StyleSheetCache.get(ssid);
+
+                var href = parentStyleSheet.externalURL ? parentStyleSheet.externalURL : parentStyleSheet.href;  // Null means inline
+
+                var instance = null;
+                //var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument);
+
+                var isSystemSheet = false;
+                //var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet);
+
+                if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules
+                    continue;
+
+                if (!href)
+                    href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452
+
+                var props = this.getRuleProperties(this.context, rule, inheritMode);
+                if (inheritMode && !props.length)
+                    continue;
+
+                //
+                //var line = domUtils.getRuleLine(rule);
+                // TODO: xxxpedro CSS line number
+                var line = ruleData.lineNo;
+
+                var ruleId = rule.selectorText+"/"+line;
+                var sourceLink = new SourceLink(href, line, "css", rule, instance);
+
+                this.markOverridenProps(props, usedProps, inheritMode);
+
+                rules.splice(0, 0, {rule: rule, id: ruleId,
+                        selector: ruleData.selector, sourceLink: sourceLink,
+                        props: props, inherited: inheritMode,
+                        isSystemSheet: isSystemSheet});
+            }
+        }
+
+        if (element.style)
+            this.getStyleProperties(element, rules, usedProps, inheritMode);
+
+        if (FBTrace.DBG_CSS)
+            FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules);
+    },
+    /*
+    getElementRules: function(element, rules, usedProps, inheritMode)
+    {
+        var inspectedRules, displayedRules = {};
+        try
+        {
+            inspectedRules = domUtils ? domUtils.getCSSStyleRules(element) : null;
+        } catch (exc) {}
+
+        if (inspectedRules)
+        {
+            for (var i = 0; i < inspectedRules.Count(); ++i)
+            {
+                var rule = QI(inspectedRules.GetElementAt(i), nsIDOMCSSStyleRule);
+
+                var href = rule.parentStyleSheet.href;  // Null means inline
+
+                var instance = getInstanceForStyleSheet(rule.parentStyleSheet, element.ownerDocument);
+
+                var isSystemSheet = isSystemStyleSheet(rule.parentStyleSheet);
+                if (!Firebug.showUserAgentCSS && isSystemSheet) // This removes user agent rules
+                    continue;
+                if (!href)
+                    href = element.ownerDocument.location.href; // http://code.google.com/p/fbug/issues/detail?id=452
+
+                var props = this.getRuleProperties(this.context, rule, inheritMode);
+                if (inheritMode && !props.length)
+                    continue;
+
+                var line = domUtils.getRuleLine(rule);
+                var ruleId = rule.selectorText+"/"+line;
+                var sourceLink = new SourceLink(href, line, "css", rule, instance);
+
+                this.markOverridenProps(props, usedProps, inheritMode);
+
+                rules.splice(0, 0, {rule: rule, id: ruleId,
+                        selector: rule.selectorText, sourceLink: sourceLink,
+                        props: props, inherited: inheritMode,
+                        isSystemSheet: isSystemSheet});
+            }
+        }
+
+        if (element.style)
+            this.getStyleProperties(element, rules, usedProps, inheritMode);
+
+        if (FBTrace.DBG_CSS)
+            FBTrace.sysout("getElementRules "+rules.length+" rules for "+getElementXPath(element), rules);
+    },
+    /**/
+    markOverridenProps: function(props, usedProps, inheritMode)
+    {
+        for (var i = 0; i < props.length; ++i)
+        {
+            var prop = props[i];
+            if ( usedProps.hasOwnProperty(prop.name) )
+            {
+                var deadProps = usedProps[prop.name]; // all previous occurrences of this property
+                for (var j = 0; j < deadProps.length; ++j)
+                {
+                    var deadProp = deadProps[j];
+                    if (!deadProp.disabled && !deadProp.wasInherited && deadProp.important && !prop.important)
+                        prop.overridden = true;  // new occurrence overridden
+                    else if (!prop.disabled)
+                        deadProp.overridden = true;  // previous occurrences overridden
+                }
+            }
+            else
+                usedProps[prop.name] = [];
+
+            prop.wasInherited = inheritMode ? true : false;
+            usedProps[prop.name].push(prop);  // all occurrences of a property seen so far, by name
+        }
+    },
+
+    getStyleProperties: function(element, rules, usedProps, inheritMode)
+    {
+        var props = this.parseCSSProps(element.style, inheritMode);
+        this.addOldProperties(this.context, getElementXPath(element), inheritMode, props);
+
+        sortProperties(props);
+        this.markOverridenProps(props, usedProps, inheritMode);
+
+        if (props.length)
+            rules.splice(0, 0,
+                    {rule: element, id: getElementXPath(element),
+                        selector: "element.style", props: props, inherited: inheritMode});
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    name: "css",
+    title: "Style",
+    parentPanel: "HTML",
+    order: 0,
+
+    initialize: function()
+    {
+        this.context = Firebug.chrome; // TODO: xxxpedro css2
+        this.document = Firebug.chrome.document; // TODO: xxxpedro css2
+
+        Firebug.CSSStyleSheetPanel.prototype.initialize.apply(this, arguments);
+
+        // TODO: xxxpedro css2
+        var selection = ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId);
+        if (selection)
+            this.select(selection, true);
+
+        //this.updateCascadeView(document.getElementsByTagName("h1")[0]);
+        //this.updateCascadeView(document.getElementById("build"));
+
+        /*
+        this.onStateChange = bindFixed(this.contentStateCheck, this);
+        this.onHoverChange = bindFixed(this.contentStateCheck, this, STATE_HOVER);
+        this.onActiveChange = bindFixed(this.contentStateCheck, this, STATE_ACTIVE);
+        /**/
+    },
+
+    ishow: function(state)
+    {
+    },
+
+    watchWindow: function(win)
+    {
+        if (domUtils)
+        {
+            // Normally these would not be required, but in order to update after the state is set
+            // using the options menu we need to monitor these global events as well
+            var doc = win.document;
+            ///addEvent(doc, "mouseover", this.onHoverChange);
+            ///addEvent(doc, "mousedown", this.onActiveChange);
+        }
+    },
+    unwatchWindow: function(win)
+    {
+        var doc = win.document;
+        ///removeEvent(doc, "mouseover", this.onHoverChange);
+        ///removeEvent(doc, "mousedown", this.onActiveChange);
+
+        if (isAncestor(this.stateChangeEl, doc))
+        {
+            this.removeStateChangeHandlers();
+        }
+    },
+
+    supportsObject: function(object)
+    {
+        return object instanceof Element ? 1 : 0;
+    },
+
+    updateView: function(element)
+    {
+        this.updateCascadeView(element);
+        if (domUtils)
+        {
+            this.contentState = safeGetContentState(element);
+            this.addStateChangeHandlers(element);
+        }
+    },
+
+    updateSelection: function(element)
+    {
+        if ( !instanceOf(element , "Element") ) // html supports SourceLink
+            return;
+
+        if (sothinkInstalled)
+        {
+            FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode);
+            return;
+        }
+
+        /*
+        if (!domUtils)
+        {
+            FirebugReps.Warning.tag.replace({object: "DOMInspectorWarning"}, this.panelNode);
+            return;
+        }
+        /**/
+
+        if (!element)
+            return;
+
+        this.updateView(element);
+    },
+
+    updateOption: function(name, value)
+    {
+        if (name == "showUserAgentCSS" || name == "expandShorthandProps")
+            this.refresh();
+    },
+
+    getOptionsMenuItems: function()
+    {
+        var ret = [
+            {label: "Show User Agent CSS", type: "checkbox", checked: Firebug.showUserAgentCSS,
+                    command: bindFixed(Firebug.togglePref, Firebug, "showUserAgentCSS") },
+            {label: "Expand Shorthand Properties", type: "checkbox", checked: Firebug.expandShorthandProps,
+                    command: bindFixed(Firebug.togglePref, Firebug, "expandShorthandProps") }
+        ];
+        if (domUtils && this.selection)
+        {
+            var state = safeGetContentState(this.selection);
+
+            ret.push("-");
+            ret.push({label: ":active", type: "checkbox", checked: state & STATE_ACTIVE,
+              command: bindFixed(this.updateContentState, this, STATE_ACTIVE, state & STATE_ACTIVE)});
+            ret.push({label: ":hover", type: "checkbox", checked: state & STATE_HOVER,
+              command: bindFixed(this.updateContentState, this, STATE_HOVER, state & STATE_HOVER)});
+        }
+        return ret;
+    },
+
+    updateContentState: function(state, remove)
+    {
+        domUtils.setContentState(remove ? this.selection.ownerDocument.documentElement : this.selection, state);
+        this.refresh();
+    },
+
+    addStateChangeHandlers: function(el)
+    {
+      this.removeStateChangeHandlers();
+
+      /*
+      addEvent(el, "focus", this.onStateChange);
+      addEvent(el, "blur", this.onStateChange);
+      addEvent(el, "mouseup", this.onStateChange);
+      addEvent(el, "mousedown", this.onStateChange);
+      addEvent(el, "mouseover", this.onStateChange);
+      addEvent(el, "mouseout", this.onStateChange);
+      /**/
+
+      this.stateChangeEl = el;
+    },
+
+    removeStateChangeHandlers: function()
+    {
+        var sel = this.stateChangeEl;
+        if (sel)
+        {
+            /*
+            removeEvent(sel, "focus", this.onStateChange);
+            removeEvent(sel, "blur", this.onStateChange);
+            removeEvent(sel, "mouseup", this.onStateChange);
+            removeEvent(sel, "mousedown", this.onStateChange);
+            removeEvent(sel, "mouseover", this.onStateChange);
+            removeEvent(sel, "mouseout", this.onStateChange);
+            /**/
+        }
+    },
+
+    contentStateCheck: function(state)
+    {
+        if (!state || this.contentState & state)
+        {
+            var timeoutRunner = bindFixed(function()
+            {
+                var newState = safeGetContentState(this.selection);
+                if (newState != this.contentState)
+                {
+                    this.context.invalidatePanels(this.name);
+                }
+            }, this);
+
+            // Delay exec until after the event has processed and the state has been updated
+            setTimeout(timeoutRunner, 0);
+        }
+    }
+});
+
+function safeGetContentState(selection)
+{
+    try
+    {
+        return domUtils.getContentState(selection);
+    }
+    catch (e)
+    {
+        if (FBTrace.DBG_ERRORS)
+            FBTrace.sysout("css.safeGetContentState; EXCEPTION", e);
+    }
+}
+
+// ************************************************************************************************
+
+function CSSComputedElementPanel() {}
+
+CSSComputedElementPanel.prototype = extend(CSSElementPanel.prototype,
+{
+    template: domplate(
+    {
+        computedTag:
+            DIV({"class": "a11yCSSView", role : "list", "aria-label" : $STR('aria.labels.computed styles')},
+                FOR("group", "$groups",
+                    H1({"class": "cssInheritHeader groupHeader focusRow", role : "listitem"},
+                        SPAN({"class": "cssInheritLabel"}, "$group.title")
+                    ),
+                    TABLE({width: "100%", role : 'group'},
+                        TBODY({role : 'presentation'},
+                            FOR("prop", "$group.props",
+                                TR({"class": 'focusRow computedStyleRow', role : 'listitem'},
+                                    TD({"class": "stylePropName", role : 'presentation'}, "$prop.name"),
+                                    TD({"class": "stylePropValue", role : 'presentation'}, "$prop.value")
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+    }),
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    updateComputedView: function(element)
+    {
+        var win = isIE ?
+                element.ownerDocument.parentWindow :
+                element.ownerDocument.defaultView;
+
+        var style = isIE ?
+                element.currentStyle :
+                win.getComputedStyle(element, "");
+
+        var groups = [];
+
+        for (var groupName in styleGroups)
+        {
+            // TODO: xxxpedro i18n $STR
+            //var title = $STR("StyleGroup-" + groupName);
+            var title = styleGroupTitles[groupName];
+            var group = {title: title, props: []};
+            groups.push(group);
+
+            var props = styleGroups[groupName];
+            for (var i = 0; i < props.length; ++i)
+            {
+                var propName = props[i];
+                var propValue = style.getPropertyValue ?
+                        style.getPropertyValue(propName) :
+                        ""+style[toCamelCase(propName)];
+
+                if (propValue === undefined || propValue === null)
+                    continue;
+
+                propValue = stripUnits(rgbToHex(propValue));
+                if (propValue)
+                    group.props.push({name: propName, value: propValue});
+            }
+        }
+
+        var result = this.template.computedTag.replace({groups: groups}, this.panelNode);
+        //dispatch([Firebug.A11yModel], 'onCSSRulesAdded', [this, result]);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    name: "computed",
+    title: "Computed",
+    parentPanel: "HTML",
+    order: 1,
+
+    updateView: function(element)
+    {
+        this.updateComputedView(element);
+    },
+
+    getOptionsMenuItems: function()
+    {
+        return [
+            {label: "Refresh", command: bind(this.refresh, this) }
+        ];
+    }
+});
+
+// ************************************************************************************************
+// CSSEditor
+
+function CSSEditor(doc)
+{
+    this.initializeInline(doc);
+}
+
+CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
+{
+    insertNewRow: function(target, insertWhere)
+    {
+        var rule = Firebug.getRepObject(target);
+        var emptyProp =
+        {
+            // TODO: xxxpedro - uses charCode(255) to force the element being rendered,
+            // allowing webkit to get the correct position of the property name "span",
+            // when inserting a new CSS rule?
+            name: "",
+            value: "",
+            important: ""
+        };
+
+        if (insertWhere == "before")
+            return CSSPropTag.tag.insertBefore({prop: emptyProp, rule: rule}, target);
+        else
+            return CSSPropTag.tag.insertAfter({prop: emptyProp, rule: rule}, target);
+    },
+
+    saveEdit: function(target, value, previousValue)
+    {
+        // We need to check the value first in order to avoid a problem in IE8
+        // See Issue 3038: Empty (null) styles when adding CSS styles in Firebug Lite
+        if (!value) return;
+
+        target.innerHTML = escapeForCss(value);
+
+        var row = getAncestorByClass(target, "cssProp");
+        if (hasClass(row, "disabledStyle"))
+            toggleClass(row, "disabledStyle");
+
+        var rule = Firebug.getRepObject(target);
+
+        if (hasClass(target, "cssPropName"))
+        {
+            if (value && previousValue != value)  // name of property has changed.
+            {
+                var propValue = getChildByClass(row, "cssPropValue")[textContent];
+                var parsedValue = parsePriority(propValue);
+
+                if (propValue && propValue != "undefined") {
+                    if (FBTrace.DBG_CSS)
+                        FBTrace.sysout("CSSEditor.saveEdit : "+previousValue+"->"+value+" = "+propValue+"\n");
+                    if (previousValue)
+                        Firebug.CSSModule.removeProperty(rule, previousValue);
+                    Firebug.CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority);
+                }
+            }
+            else if (!value) // name of the property has been deleted, so remove the property.
+                Firebug.CSSModule.removeProperty(rule, previousValue);
+        }
+        else if (getAncestorByClass(target, "cssPropValue"))
+        {
+            var propName = getChildByClass(row, "cssPropName")[textContent];
+            var propValue = getChildByClass(row, "cssPropValue")[textContent];
+
+            if (FBTrace.DBG_CSS)
+            {
+                FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +" = "+propValue+"\n");
+               // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style);
+            }
+
+            if (value && value != "null")
+            {
+                var parsedValue = parsePriority(value);
+                Firebug.CSSModule.setProperty(rule, propName, parsedValue.value, parsedValue.priority);
+            }
+            else if (previousValue && previousValue != "null")
+                Firebug.CSSModule.removeProperty(rule, propName);
+        }
+
+        this.panel.markChange(this.panel.name == "stylesheet");
+    },
+
+    advanceToNext: function(target, charCode)
+    {
+        if (charCode == 58 /*":"*/ && hasClass(target, "cssPropName"))
+            return true;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    getAutoCompleteRange: function(value, offset)
+    {
+        if (hasClass(this.target, "cssPropName"))
+            return {start: 0, end: value.length-1};
+        else
+            return parseCSSValue(value, offset);
+    },
+
+    getAutoCompleteList: function(preExpr, expr, postExpr)
+    {
+        if (hasClass(this.target, "cssPropName"))
+        {
+            return getCSSPropertyNames();
+        }
+        else
+        {
+            var row = getAncestorByClass(this.target, "cssProp");
+            var propName = getChildByClass(row, "cssPropName")[textContent];
+            return getCSSKeywordsByProperty(propName);
+        }
+    }
+});
+
+//************************************************************************************************
+//CSSRuleEditor
+
+function CSSRuleEditor(doc)
+{
+    this.initializeInline(doc);
+    this.completeAsYouType = false;
+}
+CSSRuleEditor.uniquifier = 0;
+CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
+{
+    insertNewRow: function(target, insertWhere)
+    {
+         var emptyRule = {
+                 selector: "",
+                 id: "",
+                 props: [],
+                 isSelectorEditable: true
+         };
+
+         if (insertWhere == "before")
+             return CSSStyleRuleTag.tag.insertBefore({rule: emptyRule}, target);
+         else
+             return CSSStyleRuleTag.tag.insertAfter({rule: emptyRule}, target);
+    },
+
+    saveEdit: function(target, value, previousValue)
+    {
+        if (FBTrace.DBG_CSS)
+            FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "'  '" + previousValue + "'", target);
+
+        target.innerHTML = escapeForCss(value);
+
+        if (value === previousValue)     return;
+
+        var row = getAncestorByClass(target, "cssRule");
+        var styleSheet = this.panel.location;
+        styleSheet = styleSheet.editStyleSheet ? styleSheet.editStyleSheet.sheet : styleSheet;
+
+        var cssRules = styleSheet.cssRules;
+        var rule = Firebug.getRepObject(target), oldRule = rule;
+        var ruleIndex = cssRules.length;
+        if (rule || Firebug.getRepObject(row.nextSibling))
+        {
+            var searchRule = rule || Firebug.getRepObject(row.nextSibling);
+            for (ruleIndex=0; ruleIndex<cssRules.length && searchRule!=cssRules[ruleIndex]; ruleIndex++) {}
+        }
+
+        // Delete in all cases except for new add
+        // We want to do this before the insert to ease change tracking
+        if (oldRule)
+        {
+            Firebug.CSSModule.deleteRule(styleSheet, ruleIndex);
+        }
+
+        // Firefox does not follow the spec for the update selector text case.
+        // When attempting to update the value, firefox will silently fail.
+        // See https://bugzilla.mozilla.org/show_bug.cgi?id=37468 for the quite
+        // old discussion of this bug.
+        // As a result we need to recreate the style every time the selector
+        // changes.
+        if (value)
+        {
+            var cssText = [ value, "{" ];
+            var props = row.getElementsByClassName("cssProp");
+            for (var i = 0; i < props.length; i++) {
+                var propEl = props[i];
+                if (!hasClass(propEl, "disabledStyle")) {
+                    cssText.push(getChildByClass(propEl, "cssPropName")[textContent]);
+                    cssText.push(":");
+                    cssText.push(getChildByClass(propEl, "cssPropValue")[textContent]);
+                    cssText.push(";");
+                }
+            }
+            cssText.push("}");
+            cssText = cssText.join("");
+
+            try
+            {
+                var insertLoc = Firebug.CSSModule.insertRule(styleSheet, cssText, ruleIndex);
+                rule = cssRules[insertLoc];
+                ruleIndex++;
+            }
+            catch (err)
+            {
+                if (FBTrace.DBG_CSS || FBTrace.DBG_ERRORS)
+                    FBTrace.sysout("CSS Insert Error: "+err, err);
+
+                target.innerHTML = escapeForCss(previousValue);
+                row.repObject = undefined;
+                return;
+            }
+        } else {
+            rule = undefined;
+        }
+
+        // Update the rep object
+        row.repObject = rule;
+        if (!oldRule)
+        {
+            // Who knows what the domutils will return for rule line
+            // for a recently created rule. To be safe we just generate
+            // a unique value as this is only used as an internal key.
+            var ruleId = "new/"+value+"/"+(++CSSRuleEditor.uniquifier);
+            row.setAttribute("ruleId", ruleId);
+        }
+
+        this.panel.markChange(this.panel.name == "stylesheet");
+    }
+});
+
+// ************************************************************************************************
+// StyleSheetEditor
+
+function StyleSheetEditor(doc)
+{
+    this.box = this.tag.replace({}, doc, this);
+    this.input = this.box.firstChild;
+}
+
+StyleSheetEditor.prototype = domplate(Firebug.BaseEditor,
+{
+    multiLine: true,
+
+    tag: DIV(
+        TEXTAREA({"class": "styleSheetEditor fullPanelEditor", oninput: "$onInput"})
+    ),
+
+    getValue: function()
+    {
+        return this.input.value;
+    },
+
+    setValue: function(value)
+    {
+        return this.input.value = value;
+    },
+
+    show: function(target, panel, value, textSize, targetSize)
+    {
+        this.target = target;
+        this.panel = panel;
+
+        this.panel.panelNode.appendChild(this.box);
+
+        this.input.value = value;
+        this.input.focus();
+
+        var command = Firebug.chrome.$("cmd_toggleCSSEditing");
+        command.setAttribute("checked", true);
+    },
+
+    hide: function()
+    {
+        var command = Firebug.chrome.$("cmd_toggleCSSEditing");
+        command.setAttribute("checked", false);
+
+        if (this.box.parentNode == this.panel.panelNode)
+            this.panel.panelNode.removeChild(this.box);
+
+        delete this.target;
+        delete this.panel;
+        delete this.styleSheet;
+    },
+
+    saveEdit: function(target, value, previousValue)
+    {
+        Firebug.CSSModule.freeEdit(this.styleSheet, value);
+    },
+
+    endEditing: function()
+    {
+        this.panel.refresh();
+        return true;
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onInput: function()
+    {
+        Firebug.Editor.update();
+    },
+
+    scrollToLine: function(line, offset)
+    {
+        this.startMeasuring(this.input);
+        var lineHeight = this.measureText().height;
+        this.stopMeasuring();
+
+        this.input.scrollTop = (line * lineHeight) + offset;
+    }
+});
+
+// ************************************************************************************************
+// Local Helpers
+
+var rgbToHex = function rgbToHex(value)
+{
+    return value.replace(/\brgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)/gi, rgbToHexReplacer);
+};
+
+var rgbToHexReplacer = function(_, r, g, b) {
+    return '#' + ((1 << 24) + (r << 16) + (g << 8) + (b << 0)).toString(16).substr(-6).toUpperCase();
+};
+
+var stripUnits = function stripUnits(value)
+{
+    // remove units from '0px', '0em' etc. leave non-zero units in-tact.
+    return value.replace(/(url\(.*?\)|[^0]\S*\s*)|0(%|em|ex|px|in|cm|mm|pt|pc)(\s|$)/gi, stripUnitsReplacer);
+};
+
+var stripUnitsReplacer = function(_, skip, remove, whitespace) {
+    return skip || ('0' + whitespace);
+};
+
+function parsePriority(value)
+{
+    var rePriority = /(.*?)\s*(!important)?$/;
+    var m = rePriority.exec(value);
+    var propValue = m ? m[1] : "";
+    var priority = m && m[2] ? "important" : "";
+    return {value: propValue, priority: priority};
+}
+
+function parseURLValue(value)
+{
+    var m = reURL.exec(value);
+    return m ? m[1] : "";
+}
+
+function parseRepeatValue(value)
+{
+    var m = reRepeat.exec(value);
+    return m ? m[0] : "";
+}
+
+function parseCSSValue(value, offset)
+{
+    var start = 0;
+    var m;
+    while (1)
+    {
+        m = reSplitCSS.exec(value);
+        if (m && m.index+m[0].length < offset)
+        {
+            value = value.substr(m.index+m[0].length);
+            start += m.index+m[0].length;
+            offset -= m.index+m[0].length;
+        }
+        else
+            break;
+    }
+
+    if (m)
+    {
+        var type;
+        if (m[1])
+            type = "url";
+        else if (m[2] || m[3])
+            type = "rgb";
+        else if (m[4])
+            type = "int";
+
+        return {value: m[0], start: start+m.index, end: start+m.index+(m[0].length-1), type: type};
+    }
+}
+
+function findPropByName(props, name)
+{
+    for (var i = 0; i < props.length; ++i)
+    {
+        if (props[i].name == name)
+            return i;
+    }
+}
+
+function sortProperties(props)
+{
+    props.sort(function(a, b)
+    {
+        return a.name > b.name ? 1 : -1;
+    });
+}
+
+function getTopmostRuleLine(panelNode)
+{
+    for (var child = panelNode.firstChild; child; child = child.nextSibling)
+    {
+        if (child.offsetTop+child.offsetHeight > panelNode.scrollTop)
+        {
+            var rule = child.repObject;
+            if (rule)
+                return {
+                    line: domUtils.getRuleLine(rule),
+                    offset: panelNode.scrollTop-child.offsetTop
+                };
+        }
+    }
+    return 0;
+}
+
+function getStyleSheetCSS(sheet, context)
+{
+    if (sheet.ownerNode instanceof HTMLStyleElement)
+        return sheet.ownerNode.innerHTML;
+    else
+        return context.sourceCache.load(sheet.href).join("");
+}
+
+function getStyleSheetOwnerNode(sheet) {
+    for (; sheet && !sheet.ownerNode; sheet = sheet.parentStyleSheet);
+
+    return sheet.ownerNode;
+}
+
+function scrollSelectionIntoView(panel)
+{
+    var selCon = getSelectionController(panel);
+    selCon.scrollSelectionIntoView(
+            nsISelectionController.SELECTION_NORMAL,
+            nsISelectionController.SELECTION_FOCUS_REGION, true);
+}
+
+function getSelectionController(panel)
+{
+    var browser = Firebug.chrome.getPanelBrowser(panel);
+    return browser.docShell.QueryInterface(nsIInterfaceRequestor)
+        .getInterface(nsISelectionDisplay)
+        .QueryInterface(nsISelectionController);
+}
+
+// ************************************************************************************************
+
+Firebug.registerModule(Firebug.CSSModule);
+Firebug.registerPanel(Firebug.CSSStyleSheetPanel);
+Firebug.registerPanel(CSSElementPanel);
+Firebug.registerPanel(CSSComputedElementPanel);
+
+// ************************************************************************************************
+
+}});
+
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Script Module
+
+Firebug.Script = extend(Firebug.Module,
+{
+    getPanel: function()
+    {
+        return Firebug.chrome ? Firebug.chrome.getPanel("Script") : null;
+    },
+
+    selectSourceCode: function(index)
+    {
+        this.getPanel().selectSourceCode(index);
+    }
+});
+
+Firebug.registerModule(Firebug.Script);
+
+
+// ************************************************************************************************
+// Script Panel
+
+function ScriptPanel(){};
+
+ScriptPanel.prototype = extend(Firebug.Panel,
+{
+    name: "Script",
+    title: "Script",
+
+    selectIndex: 0, // index of the current selectNode's option
+    sourceIndex: -1, // index of the script node, based in doc.getElementsByTagName("script")
+
+    options: {
+        hasToolButtons: true
+    },
+
+    create: function()
+    {
+        Firebug.Panel.create.apply(this, arguments);
+
+        this.onChangeSelect = bind(this.onChangeSelect, this);
+
+        var doc = Firebug.browser.document;
+        var scripts = doc.getElementsByTagName("script");
+        var selectNode = this.selectNode = createElement("select");
+
+        for(var i=0, script; script=scripts[i]; i++)
+        {
+            // Don't show Firebug Lite source code in the list of options
+            if (Firebug.ignoreFirebugElements && script.getAttribute("firebugIgnore"))
+                continue;
+
+            var fileName = getFileName(script.src) || getFileName(doc.location.href);
+            var option = createElement("option", {value:i});
+
+            option.appendChild(Firebug.chrome.document.createTextNode(fileName));
+            selectNode.appendChild(option);
+        };
+
+        this.toolButtonsNode.appendChild(selectNode);
+    },
+
+    initialize: function()
+    {
+        // we must render the code first, so the persistent state can be restore
+        this.selectSourceCode(this.selectIndex);
+
+        Firebug.Panel.initialize.apply(this, arguments);
+
+        addEvent(this.selectNode, "change", this.onChangeSelect);
+    },
+
+    shutdown: function()
+    {
+        removeEvent(this.selectNode, "change", this.onChangeSelect);
+
+        Firebug.Panel.shutdown.apply(this, arguments);
+    },
+
+    detach: function(oldChrome, newChrome)
+    {
+        Firebug.Panel.detach.apply(this, arguments);
+
+        var oldPanel = oldChrome.getPanel("Script");
+        var index = oldPanel.selectIndex;
+
+        this.selectNode.selectedIndex = index;
+        this.selectIndex = index;
+        this.sourceIndex = -1;
+    },
+
+    onChangeSelect: function(event)
+    {
+        var select = this.selectNode;
+
+        this.selectIndex = select.selectedIndex;
+
+        var option = select.options[select.selectedIndex];
+        if (!option)
+            return;
+
+        var selectedSourceIndex = parseInt(option.value);
+
+        this.renderSourceCode(selectedSourceIndex);
+    },
+
+    selectSourceCode: function(index)
+    {
+        var select = this.selectNode;
+        select.selectedIndex = index;
+
+        var option = select.options[index];
+        if (!option)
+            return;
+
+        var selectedSourceIndex = parseInt(option.value);
+
+        this.renderSourceCode(selectedSourceIndex);
+    },
+
+    renderSourceCode: function(index)
+    {
+        if (this.sourceIndex != index)
+        {
+            var renderProcess = function renderProcess(src)
+            {
+                var html = [],
+                    hl = 0;
+
+                src = isIE && !isExternal ?
+                        src+'\n' :  // IE put an extra line when reading source of local resources
+                        '\n'+src;
+
+                // find the number of lines of code
+                src = src.replace(/\n\r|\r\n/g, "\n");
+                var match = src.match(/[\n]/g);
+                var lines=match ? match.length : 0;
+
+                // render the full source code + line numbers html
+                html[hl++] = '<div><div class="sourceBox" style="left:';
+                html[hl++] = 35 + 7*(lines+'').length;
+                html[hl++] = 'px;"><pre class="sourceCode">';
+                html[hl++] = escapeHTML(src);
+                html[hl++] = '</pre></div><div class="lineNo">';
+
+                // render the line number divs
+                for(var l=1, lines; l<=lines; l++)
+                {
+                    html[hl++] = '<div line="';
+                    html[hl++] = l;
+                    html[hl++] = '">';
+                    html[hl++] = l;
+                    html[hl++] = '</div>';
+                }
+
+                html[hl++] = '</div></div>';
+
+                updatePanel(html);
+            };
+
+            var updatePanel = function(html)
+            {
+                self.panelNode.innerHTML = html.join("");
+
+                // IE needs this timeout, otherwise the panel won't scroll
+                setTimeout(function(){
+                    self.synchronizeUI();
+                },0);
+            };
+
+            var onFailure = function()
+            {
+                FirebugReps.Warning.tag.replace({object: "AccessRestricted"}, self.panelNode);
+            };
+
+            var self = this;
+
+            var doc = Firebug.browser.document;
+            var script = doc.getElementsByTagName("script")[index];
+            var url = getScriptURL(script);
+            var isExternal = url && url != doc.location.href;
+
+            try
+            {
+                if (Firebug.disableResourceFetching)
+                {
+                    renderProcess(Firebug.Lite.Proxy.fetchResourceDisabledMessage);
+                }
+                else if (isExternal)
+                {
+                    Ajax.request({url: url, onSuccess: renderProcess, onFailure: onFailure});
+                }
+                else
+                {
+                    var src = script.innerHTML;
+                    renderProcess(src);
+                }
+            }
+            catch(e)
+            {
+                onFailure();
+            }
+
+            this.sourceIndex = index;
+        }
+    }
+});
+
+Firebug.registerPanel(ScriptPanel);
+
+
+// ************************************************************************************************
+
+
+var getScriptURL = function getScriptURL(script)
+{
+    var reFile = /([^\/\?#]+)(#.+)?$/;
+    var rePath = /^(.*\/)/;
+    var reProtocol = /^\w+:\/\//;
+    var path = null;
+    var doc = Firebug.browser.document;
+
+    var file = reFile.exec(script.src);
+
+    if (file)
+    {
+        var fileName = file[1];
+        var fileOptions = file[2];
+
+        // absolute path
+        if (reProtocol.test(script.src)) {
+            path = rePath.exec(script.src)[1];
+
+        }
+        // relative path
+        else
+        {
+            var r = rePath.exec(script.src);
+            var src = r ? r[1] : script.src;
+            var backDir = /^((?:\.\.\/)+)(.*)/.exec(src);
+            var reLastDir = /^(.*\/)[^\/]+\/$/;
+            path = rePath.exec(doc.location.href)[1];
+
+            // "../some/path"
+            if (backDir)
+            {
+                var j = backDir[1].length/3;
+                var p;
+                while (j-- > 0)
+                    path = reLastDir.exec(path)[1];
+
+                path += backDir[2];
+            }
+
+            else if(src.indexOf("/") != -1)
+            {
+                // "./some/path"
+                if(/^\.\/./.test(src))
+                {
+                    path += src.substring(2);
+                }
+                // "/some/path"
+                else if(/^\/./.test(src))
+                {
+                    var domain = /^(\w+:\/\/[^\/]+)/.exec(path);
+                    path = domain[1] + src;
+                }
+                // "some/path"
+                else
+                {
+                    path += src;
+                }
+            }
+        }
+    }
+
+    var m = path && path.match(/([^\/]+)\/$/) || null;
+
+    if (path && m)
+    {
+        return path + fileName;
+    }
+};
+
+var getFileName = function getFileName(path)
+{
+    if (!path) return "";
+
+    var match = path && path.match(/[^\/]+(\?.*)?(#.*)?$/);
+
+    return match && match[0] || path;
+};
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var ElementCache = Firebug.Lite.Cache.Element;
+
+var insertSliceSize = 18;
+var insertInterval = 40;
+
+var ignoreVars =
+{
+    "__firebug__": 1,
+    "eval": 1,
+
+    // We are forced to ignore Java-related variables, because
+    // trying to access them causes browser freeze
+    "java": 1,
+    "sun": 1,
+    "Packages": 1,
+    "JavaArray": 1,
+    "JavaMember": 1,
+    "JavaObject": 1,
+    "JavaClass": 1,
+    "JavaPackage": 1,
+    "_firebug": 1,
+    "_FirebugConsole": 1,
+    "_FirebugCommandLine": 1
+};
+
+if (Firebug.ignoreFirebugElements)
+    ignoreVars[Firebug.Lite.Cache.ID] = 1;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+var memberPanelRep =
+    isIE6 ?
+    {"class": "memberLabel $member.type\\Label", href: "javacript:void(0)"}
+    :
+    {"class": "memberLabel $member.type\\Label"};
+
+var RowTag =
+    TR({"class": "memberRow $member.open $member.type\\Row", $hasChildren: "$member.hasChildren", role : 'presentation',
+        level: "$member.level"},
+        TD({"class": "memberLabelCell", style: "padding-left: $member.indent\\px", role : 'presentation'},
+            A(memberPanelRep,
+                SPAN({}, "$member.name")
+            )
+        ),
+        TD({"class": "memberValueCell", role : 'presentation'},
+            TAG("$member.tag", {object: "$member.value"})
+        )
+    );
+
+var WatchRowTag =
+    TR({"class": "watchNewRow", level: 0},
+        TD({"class": "watchEditCell", colspan: 2},
+            DIV({"class": "watchEditBox a11yFocusNoTab", role: "button", 'tabindex' : '0',
+                'aria-label' : $STR('press enter to add new watch expression')},
+                    $STR("NewWatch")
+            )
+        )
+    );
+
+var SizerRow =
+    TR({role : 'presentation'},
+        TD({width: "30%"}),
+        TD({width: "70%"})
+    );
+
+var domTableClass = isIElt8 ? "domTable domTableIE" : "domTable";
+var DirTablePlate = domplate(Firebug.Rep,
+{
+    tag:
+        TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0, onclick: "$onClick", role :"tree"},
+            TBODY({role: 'presentation'},
+                SizerRow,
+                FOR("member", "$object|memberIterator", RowTag)
+            )
+        ),
+
+    watchTag:
+        TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0,
+               _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'},
+            TBODY({role : 'presentation'},
+                SizerRow,
+                WatchRowTag
+            )
+        ),
+
+    tableTag:
+        TABLE({"class": domTableClass, cellpadding: 0, cellspacing: 0,
+            _toggles: "$toggles", _domPanel: "$domPanel", onclick: "$onClick", role : 'tree'},
+            TBODY({role : 'presentation'},
+                SizerRow
+            )
+        ),
+
+    rowTag:
+        FOR("member", "$members", RowTag),
+
+    memberIterator: function(object, level)
+    {
+        return getMembers(object, level);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onClick: function(event)
+    {
+        if (!isLeftClick(event))
+            return;
+
+        var target = event.target || event.srcElement;
+
+        var row = getAncestorByClass(target, "memberRow");
+        var label = getAncestorByClass(target, "memberLabel");
+        if (label && hasClass(row, "hasChildren"))
+        {
+            var row = label.parentNode.parentNode;
+            this.toggleRow(row);
+        }
+        else
+        {
+            var object = Firebug.getRepObject(target);
+            if (typeof(object) == "function")
+            {
+                Firebug.chrome.select(object, "script");
+                cancelEvent(event);
+            }
+            else if (event.detail == 2 && !object)
+            {
+                var panel = row.parentNode.parentNode.domPanel;
+                if (panel)
+                {
+                    var rowValue = panel.getRowPropertyValue(row);
+                    if (typeof(rowValue) == "boolean")
+                        panel.setPropertyValue(row, !rowValue);
+                    else
+                        panel.editProperty(row);
+
+                    cancelEvent(event);
+                }
+            }
+        }
+
+        return false;
+    },
+
+    toggleRow: function(row)
+    {
+        var level = parseInt(row.getAttribute("level"));
+        var toggles = row.parentNode.parentNode.toggles;
+
+        if (hasClass(row, "opened"))
+        {
+            removeClass(row, "opened");
+
+            if (toggles)
+            {
+                var path = getPath(row);
+
+                // Remove the path from the toggle tree
+                for (var i = 0; i < path.length; ++i)
+                {
+                    if (i == path.length-1)
+                        delete toggles[path[i]];
+                    else
+                        toggles = toggles[path[i]];
+                }
+            }
+
+            var rowTag = this.rowTag;
+            var tbody = row.parentNode;
+
+            setTimeout(function()
+            {
+                for (var firstRow = row.nextSibling; firstRow; firstRow = row.nextSibling)
+                {
+                    if (parseInt(firstRow.getAttribute("level")) <= level)
+                        break;
+
+                    tbody.removeChild(firstRow);
+                }
+            }, row.insertTimeout ? row.insertTimeout : 0);
+        }
+        else
+        {
+            setClass(row, "opened");
+
+            if (toggles)
+            {
+                var path = getPath(row);
+
+                // Mark the path in the toggle tree
+                for (var i = 0; i < path.length; ++i)
+                {
+                    var name = path[i];
+                    if (toggles.hasOwnProperty(name))
+                        toggles = toggles[name];
+                    else
+                        toggles = toggles[name] = {};
+                }
+            }
+
+            var value = row.lastChild.firstChild.repObject;
+            var members = getMembers(value, level+1);
+
+            var rowTag = this.rowTag;
+            var lastRow = row;
+
+            var delay = 0;
+            //var setSize = members.length;
+            //var rowCount = 1;
+            while (members.length)
+            {
+                with({slice: members.splice(0, insertSliceSize), isLast: !members.length})
+                {
+                    setTimeout(function()
+                    {
+                        if (lastRow.parentNode)
+                        {
+                            var result = rowTag.insertRows({members: slice}, lastRow);
+                            lastRow = result[1];
+                            //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [null, result, rowCount, setSize]);
+                            //rowCount += insertSliceSize;
+                        }
+                        if (isLast)
+                            row.removeAttribute("insertTimeout");
+                    }, delay);
+                }
+
+                delay += insertInterval;
+            }
+
+            row.insertTimeout = delay;
+        }
+    }
+});
+
+
+
+// ************************************************************************************************
+
+Firebug.DOMBasePanel = function() {};
+
+Firebug.DOMBasePanel.prototype = extend(Firebug.Panel,
+{
+    tag: DirTablePlate.tableTag,
+
+    getRealObject: function(object)
+    {
+        // TODO: Move this to some global location
+        // TODO: Unwrapping should be centralized rather than sprinkling it around ad hoc.
+        // TODO: We might be able to make this check more authoritative with QueryInterface.
+        if (!object) return object;
+        if (object.wrappedJSObject) return object.wrappedJSObject;
+        return object;
+    },
+
+    rebuild: function(update, scrollTop)
+    {
+        //dispatch([Firebug.A11yModel], 'onBeforeDomUpdateSelection', [this]);
+        var members = getMembers(this.selection);
+        expandMembers(members, this.toggles, 0, 0);
+
+        this.showMembers(members, update, scrollTop);
+
+        //TODO: xxxpedro statusbar
+        if (!this.parentPanel)
+            updateStatusBar(this);
+    },
+
+    showMembers: function(members, update, scrollTop)
+    {
+        // If we are still in the midst of inserting rows, cancel all pending
+        // insertions here - this is a big speedup when stepping in the debugger
+        if (this.timeouts)
+        {
+            for (var i = 0; i < this.timeouts.length; ++i)
+                this.context.clearTimeout(this.timeouts[i]);
+            delete this.timeouts;
+        }
+
+        if (!members.length)
+            return this.showEmptyMembers();
+
+        var panelNode = this.panelNode;
+        var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop;
+
+        // If we are asked to "update" the current view, then build the new table
+        // offscreen and swap it in when it's done
+        var offscreen = update && panelNode.firstChild;
+        var dest = offscreen ? panelNode.ownerDocument : panelNode;
+
+        var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest);
+        var tbody = table.lastChild;
+        var rowTag = DirTablePlate.rowTag;
+
+        // Insert the first slice immediately
+        //var slice = members.splice(0, insertSliceSize);
+        //var result = rowTag.insertRows({members: slice}, tbody.lastChild);
+
+        //var setSize = members.length;
+        //var rowCount = 1;
+
+        var panel = this;
+        var result;
+
+        //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
+        var timeouts = [];
+
+        var delay = 0;
+
+        // enable to measure rendering performance
+        var renderStart = new Date().getTime();
+        while (members.length)
+        {
+            with({slice: members.splice(0, insertSliceSize), isLast: !members.length})
+            {
+                timeouts.push(this.context.setTimeout(function()
+                {
+                    // TODO: xxxpedro can this be a timing error related to the
+                    // "iteration number" approach insted of "duration time"?
+                    // avoid error in IE8
+                    if (!tbody.lastChild) return;
+
+                    result = rowTag.insertRows({members: slice}, tbody.lastChild);
+
+                    //rowCount += insertSliceSize;
+                    //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
+
+                    if ((panelNode.scrollHeight+panelNode.offsetHeight) >= priorScrollTop)
+                        panelNode.scrollTop = priorScrollTop;
+
+
+                    // enable to measure rendering performance
+                    //if (isLast) alert(new Date().getTime() - renderStart + "ms");
+
+
+                }, delay));
+
+                delay += insertInterval;
+            }
+        }
+
+        if (offscreen)
+        {
+            timeouts.push(this.context.setTimeout(function()
+            {
+                if (panelNode.firstChild)
+                    panelNode.replaceChild(table, panelNode.firstChild);
+                else
+                    panelNode.appendChild(table);
+
+                // Scroll back to where we were before
+                panelNode.scrollTop = priorScrollTop;
+            }, delay));
+        }
+        else
+        {
+            timeouts.push(this.context.setTimeout(function()
+            {
+                panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop;
+            }, delay));
+        }
+        this.timeouts = timeouts;
+    },
+
+    /*
+    // new
+    showMembers: function(members, update, scrollTop)
+    {
+        // If we are still in the midst of inserting rows, cancel all pending
+        // insertions here - this is a big speedup when stepping in the debugger
+        if (this.timeouts)
+        {
+            for (var i = 0; i < this.timeouts.length; ++i)
+                this.context.clearTimeout(this.timeouts[i]);
+            delete this.timeouts;
+        }
+
+        if (!members.length)
+            return this.showEmptyMembers();
+
+        var panelNode = this.panelNode;
+        var priorScrollTop = scrollTop == undefined ? panelNode.scrollTop : scrollTop;
+
+        // If we are asked to "update" the current view, then build the new table
+        // offscreen and swap it in when it's done
+        var offscreen = update && panelNode.firstChild;
+        var dest = offscreen ? panelNode.ownerDocument : panelNode;
+
+        var table = this.tag.replace({domPanel: this, toggles: this.toggles}, dest);
+        var tbody = table.lastChild;
+        var rowTag = DirTablePlate.rowTag;
+
+        // Insert the first slice immediately
+        //var slice = members.splice(0, insertSliceSize);
+        //var result = rowTag.insertRows({members: slice}, tbody.lastChild);
+
+        //var setSize = members.length;
+        //var rowCount = 1;
+
+        var panel = this;
+        var result;
+
+        //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
+        var timeouts = [];
+
+        var delay = 0;
+        var _insertSliceSize = insertSliceSize;
+        var _insertInterval = insertInterval;
+
+        // enable to measure rendering performance
+        var renderStart = new Date().getTime();
+        var lastSkip = renderStart, now;
+
+        while (members.length)
+        {
+            with({slice: members.splice(0, _insertSliceSize), isLast: !members.length})
+            {
+                var _tbody = tbody;
+                var _rowTag = rowTag;
+                var _panelNode = panelNode;
+                var _priorScrollTop = priorScrollTop;
+
+                timeouts.push(this.context.setTimeout(function()
+                {
+                    // TODO: xxxpedro can this be a timing error related to the
+                    // "iteration number" approach insted of "duration time"?
+                    // avoid error in IE8
+                    if (!_tbody.lastChild) return;
+
+                    result = _rowTag.insertRows({members: slice}, _tbody.lastChild);
+
+                    //rowCount += _insertSliceSize;
+                    //dispatch([Firebug.A11yModel], 'onMemberRowSliceAdded', [panel, result, rowCount, setSize]);
+
+                    if ((_panelNode.scrollHeight + _panelNode.offsetHeight) >= _priorScrollTop)
+                        _panelNode.scrollTop = _priorScrollTop;
+
+
+                    // enable to measure rendering performance
+                    //alert("gap: " + (new Date().getTime() - lastSkip));
+                    //lastSkip = new Date().getTime();
+
+                    //if (isLast) alert("new: " + (new Date().getTime() - renderStart) + "ms");
+
+                }, delay));
+
+                delay += _insertInterval;
+            }
+        }
+
+        if (offscreen)
+        {
+            timeouts.push(this.context.setTimeout(function()
+            {
+                if (panelNode.firstChild)
+                    panelNode.replaceChild(table, panelNode.firstChild);
+                else
+                    panelNode.appendChild(table);
+
+                // Scroll back to where we were before
+                panelNode.scrollTop = priorScrollTop;
+            }, delay));
+        }
+        else
+        {
+            timeouts.push(this.context.setTimeout(function()
+            {
+                panelNode.scrollTop = scrollTop == undefined ? 0 : scrollTop;
+            }, delay));
+        }
+        this.timeouts = timeouts;
+    },
+    /**/
+
+    showEmptyMembers: function()
+    {
+        FirebugReps.Warning.tag.replace({object: "NoMembersWarning"}, this.panelNode);
+    },
+
+    findPathObject: function(object)
+    {
+        var pathIndex = -1;
+        for (var i = 0; i < this.objectPath.length; ++i)
+        {
+            // IE needs === instead of == or otherwise some objects will
+            // be considered equal to different objects, returning the
+            // wrong index of the objectPath array
+            if (this.getPathObject(i) === object)
+                return i;
+        }
+
+        return -1;
+    },
+
+    getPathObject: function(index)
+    {
+        var object = this.objectPath[index];
+
+        if (object instanceof Property)
+            return object.getObject();
+        else
+            return object;
+    },
+
+    getRowObject: function(row)
+    {
+        var object = getRowOwnerObject(row);
+        return object ? object : this.selection;
+    },
+
+    getRowPropertyValue: function(row)
+    {
+        var object = this.getRowObject(row);
+        object = this.getRealObject(object);
+        if (object)
+        {
+            var propName = getRowName(row);
+
+            if (object instanceof jsdIStackFrame)
+                return Firebug.Debugger.evaluate(propName, this.context);
+            else
+                return object[propName];
+        }
+    },
+    /*
+    copyProperty: function(row)
+    {
+        var value = this.getRowPropertyValue(row);
+        copyToClipboard(value);
+    },
+
+    editProperty: function(row, editValue)
+    {
+        if (hasClass(row, "watchNewRow"))
+        {
+            if (this.context.stopped)
+                Firebug.Editor.startEditing(row, "");
+            else if (Firebug.Console.isAlwaysEnabled())  // not stopped in debugger, need command line
+            {
+                if (Firebug.CommandLine.onCommandLineFocus())
+                    Firebug.Editor.startEditing(row, "");
+                else
+                    row.innerHTML = $STR("warning.Command line blocked?");
+            }
+            else
+                row.innerHTML = $STR("warning.Console must be enabled");
+        }
+        else if (hasClass(row, "watchRow"))
+            Firebug.Editor.startEditing(row, getRowName(row));
+        else
+        {
+            var object = this.getRowObject(row);
+            this.context.thisValue = object;
+
+            if (!editValue)
+            {
+                var propValue = this.getRowPropertyValue(row);
+
+                var type = typeof(propValue);
+                if (type == "undefined" || type == "number" || type == "boolean")
+                    editValue = propValue;
+                else if (type == "string")
+                    editValue = "\"" + escapeJS(propValue) + "\"";
+                else if (propValue == null)
+                    editValue = "null";
+                else if (object instanceof Window || object instanceof jsdIStackFrame)
+                    editValue = getRowName(row);
+                else
+                    editValue = "this." + getRowName(row);
+            }
+
+
+            Firebug.Editor.startEditing(row, editValue);
+        }
+    },
+
+    deleteProperty: function(row)
+    {
+        if (hasClass(row, "watchRow"))
+            this.deleteWatch(row);
+        else
+        {
+            var object = getRowOwnerObject(row);
+            if (!object)
+                object = this.selection;
+            object = this.getRealObject(object);
+
+            if (object)
+            {
+                var name = getRowName(row);
+                try
+                {
+                    delete object[name];
+                }
+                catch (exc)
+                {
+                    return;
+                }
+
+                this.rebuild(true);
+                this.markChange();
+            }
+        }
+    },
+
+    setPropertyValue: function(row, value)  // value must be string
+    {
+        if(FBTrace.DBG_DOM)
+        {
+            FBTrace.sysout("row: "+row);
+            FBTrace.sysout("value: "+value+" type "+typeof(value), value);
+        }
+
+        var name = getRowName(row);
+        if (name == "this")
+            return;
+
+        var object = this.getRowObject(row);
+        object = this.getRealObject(object);
+        if (object && !(object instanceof jsdIStackFrame))
+        {
+             // unwrappedJSObject.property = unwrappedJSObject
+             Firebug.CommandLine.evaluate(value, this.context, object, this.context.getGlobalScope(),
+                 function success(result, context)
+                 {
+                     if (FBTrace.DBG_DOM)
+                         FBTrace.sysout("setPropertyValue evaluate success object["+name+"]="+result+" type "+typeof(result), result);
+                     object[name] = result;
+                 },
+                 function failed(exc, context)
+                 {
+                     try
+                     {
+                         if (FBTrace.DBG_DOM)
+                              FBTrace.sysout("setPropertyValue evaluate failed with exc:"+exc+" object["+name+"]="+value+" type "+typeof(value), exc);
+                         // If the value doesn't parse, then just store it as a string.  Some users will
+                         // not realize they're supposed to enter a JavaScript expression and just type
+                         // literal text
+                         object[name] = String(value);  // unwrappedJSobject.property = string
+                     }
+                     catch (exc)
+                     {
+                         return;
+                     }
+                  }
+             );
+        }
+        else if (this.context.stopped)
+        {
+            try
+            {
+                Firebug.CommandLine.evaluate(name+"="+value, this.context);
+            }
+            catch (exc)
+            {
+                try
+                {
+                    // See catch block above...
+                    object[name] = String(value); // unwrappedJSobject.property = string
+                }
+                catch (exc)
+                {
+                    return;
+                }
+            }
+        }
+
+        this.rebuild(true);
+        this.markChange();
+    },
+
+    highlightRow: function(row)
+    {
+        if (this.highlightedRow)
+            cancelClassTimed(this.highlightedRow, "jumpHighlight", this.context);
+
+        this.highlightedRow = row;
+
+        if (row)
+            setClassTimed(row, "jumpHighlight", this.context);
+    },/**/
+
+    onMouseMove: function(event)
+    {
+        var target = event.srcElement || event.target;
+
+        var object = getAncestorByClass(target, "objectLink-element");
+        object = object ? object.repObject : null;
+
+        if(object && instanceOf(object, "Element") && object.nodeType == 1)
+        {
+            if(object != lastHighlightedObject)
+            {
+                Firebug.Inspector.drawBoxModel(object);
+                object = lastHighlightedObject;
+            }
+        }
+        else
+            Firebug.Inspector.hideBoxModel();
+
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    create: function()
+    {
+        // TODO: xxxpedro
+        this.context = Firebug.browser;
+
+        this.objectPath = [];
+        this.propertyPath = [];
+        this.viewPath = [];
+        this.pathIndex = -1;
+        this.toggles = {};
+
+        Firebug.Panel.create.apply(this, arguments);
+
+        this.panelNode.style.padding = "0 1px";
+    },
+
+    initialize: function(){
+        Firebug.Panel.initialize.apply(this, arguments);
+
+        addEvent(this.panelNode, "mousemove", this.onMouseMove);
+    },
+
+    shutdown: function()
+    {
+        removeEvent(this.panelNode, "mousemove", this.onMouseMove);
+
+        Firebug.Panel.shutdown.apply(this, arguments);
+    },
+
+    /*
+    destroy: function(state)
+    {
+        var view = this.viewPath[this.pathIndex];
+        if (view && this.panelNode.scrollTop)
+            view.scrollTop = this.panelNode.scrollTop;
+
+        if (this.pathIndex)
+            state.pathIndex = this.pathIndex;
+        if (this.viewPath)
+            state.viewPath = this.viewPath;
+        if (this.propertyPath)
+            state.propertyPath = this.propertyPath;
+
+        if (this.propertyPath.length > 0 && !this.propertyPath[1])
+            state.firstSelection = persistObject(this.getPathObject(1), this.context);
+
+        Firebug.Panel.destroy.apply(this, arguments);
+    },
+    /**/
+
+    ishow: function(state)
+    {
+        if (this.context.loaded && !this.selection)
+        {
+            if (!state)
+            {
+                this.select(null);
+                return;
+            }
+            if (state.viewPath)
+                this.viewPath = state.viewPath;
+            if (state.propertyPath)
+                this.propertyPath = state.propertyPath;
+
+            var defaultObject = this.getDefaultSelection(this.context);
+            var selectObject = defaultObject;
+
+            if (state.firstSelection)
+            {
+                var restored = state.firstSelection(this.context);
+                if (restored)
+                {
+                    selectObject = restored;
+                    this.objectPath = [defaultObject, restored];
+                }
+                else
+                    this.objectPath = [defaultObject];
+            }
+            else
+                this.objectPath = [defaultObject];
+
+            if (this.propertyPath.length > 1)
+            {
+                for (var i = 1; i < this.propertyPath.length; ++i)
+                {
+                    var name = this.propertyPath[i];
+                    if (!name)
+                        continue;
+
+                    var object = selectObject;
+                    try
+                    {
+                        selectObject = object[name];
+                    }
+                    catch (exc)
+                    {
+                        selectObject = null;
+                    }
+
+                    if (selectObject)
+                    {
+                        this.objectPath.push(new Property(object, name));
+                    }
+                    else
+                    {
+                        // If we can't access a property, just stop
+                        this.viewPath.splice(i);
+                        this.propertyPath.splice(i);
+                        this.objectPath.splice(i);
+                        selectObject = this.getPathObject(this.objectPath.length-1);
+                        break;
+                    }
+                }
+            }
+
+            var selection = state.pathIndex <= this.objectPath.length-1
+                ? this.getPathObject(state.pathIndex)
+                : this.getPathObject(this.objectPath.length-1);
+
+            this.select(selection);
+        }
+    },
+    /*
+    hide: function()
+    {
+        var view = this.viewPath[this.pathIndex];
+        if (view && this.panelNode.scrollTop)
+            view.scrollTop = this.panelNode.scrollTop;
+    },
+    /**/
+
+    supportsObject: function(object)
+    {
+        if (object == null)
+            return 1000;
+
+        if (typeof(object) == "undefined")
+            return 1000;
+        else if (object instanceof SourceLink)
+            return 0;
+        else
+            return 1; // just agree to support everything but not agressively.
+    },
+
+    refresh: function()
+    {
+        this.rebuild(true);
+    },
+
+    updateSelection: function(object)
+    {
+        var previousIndex = this.pathIndex;
+        var previousView = previousIndex == -1 ? null : this.viewPath[previousIndex];
+
+        var newPath = this.pathToAppend;
+        delete this.pathToAppend;
+
+        var pathIndex = this.findPathObject(object);
+        if (newPath || pathIndex == -1)
+        {
+            this.toggles = {};
+
+            if (newPath)
+            {
+                // Remove everything after the point where we are inserting, so we
+                // essentially replace it with the new path
+                if (previousView)
+                {
+                    if (this.panelNode.scrollTop)
+                        previousView.scrollTop = this.panelNode.scrollTop;
+
+                    var start = previousIndex + 1,
+                        // Opera needs the length argument in splice(), otherwise
+                        // it will consider that only one element should be removed
+                        length = this.objectPath.length - start;
+
+                    this.objectPath.splice(start, length);
+                    this.propertyPath.splice(start, length);
+                    this.viewPath.splice(start, length);
+                }
+
+                var value = this.getPathObject(previousIndex);
+                if (!value)
+                {
+                    if (FBTrace.DBG_ERRORS)
+                        FBTrace.sysout("dom.updateSelection no pathObject for "+previousIndex+"\n");
+                    return;
+                }
+
+                for (var i = 0, length = newPath.length; i < length; ++i)
+                {
+                    var name = newPath[i];
+                    var object = value;
+                    try
+                    {
+                        value = value[name];
+                    }
+                    catch(exc)
+                    {
+                        if (FBTrace.DBG_ERRORS)
+                                FBTrace.sysout("dom.updateSelection FAILS at path_i="+i+" for name:"+name+"\n");
+                        return;
+                    }
+
+                    ++this.pathIndex;
+                    this.objectPath.push(new Property(object, name));
+                    this.propertyPath.push(name);
+                    this.viewPath.push({toggles: this.toggles, scrollTop: 0});
+                }
+            }
+            else
+            {
+                this.toggles = {};
+
+                var win = Firebug.browser.window;
+                //var win = this.context.getGlobalScope();
+                if (object === win)
+                {
+                    this.pathIndex = 0;
+                    this.objectPath = [win];
+                    this.propertyPath = [null];
+                    this.viewPath = [{toggles: this.toggles, scrollTop: 0}];
+                }
+                else
+                {
+                    this.pathIndex = 1;
+                    this.objectPath = [win, object];
+                    this.propertyPath = [null, null];
+                    this.viewPath = [
+                        {toggles: {}, scrollTop: 0},
+                        {toggles: this.toggles, scrollTop: 0}
+                    ];
+                }
+            }
+
+            this.panelNode.scrollTop = 0;
+            this.rebuild();
+        }
+        else
+        {
+            this.pathIndex = pathIndex;
+
+            var view = this.viewPath[pathIndex];
+            this.toggles = view.toggles;
+
+            // Persist the current scroll location
+            if (previousView && this.panelNode.scrollTop)
+                previousView.scrollTop = this.panelNode.scrollTop;
+
+            this.rebuild(false, view.scrollTop);
+        }
+    },
+
+    getObjectPath: function(object)
+    {
+        return this.objectPath;
+    },
+
+    getDefaultSelection: function()
+    {
+        return Firebug.browser.window;
+        //return this.context.getGlobalScope();
+    }/*,
+
+    updateOption: function(name, value)
+    {
+        const optionMap = {showUserProps: 1, showUserFuncs: 1, showDOMProps: 1,
+            showDOMFuncs: 1, showDOMConstants: 1};
+        if ( optionMap.hasOwnProperty(name) )
+            this.rebuild(true);
+    },
+
+    getOptionsMenuItems: function()
+    {
+        return [
+            optionMenu("ShowUserProps", "showUserProps"),
+            optionMenu("ShowUserFuncs", "showUserFuncs"),
+            optionMenu("ShowDOMProps", "showDOMProps"),
+            optionMenu("ShowDOMFuncs", "showDOMFuncs"),
+            optionMenu("ShowDOMConstants", "showDOMConstants"),
+            "-",
+            {label: "Refresh", command: bindFixed(this.rebuild, this, true) }
+        ];
+    },
+
+    getContextMenuItems: function(object, target)
+    {
+        var row = getAncestorByClass(target, "memberRow");
+
+        var items = [];
+
+        if (row)
+        {
+            var rowName = getRowName(row);
+            var rowObject = this.getRowObject(row);
+            var rowValue = this.getRowPropertyValue(row);
+
+            var isWatch = hasClass(row, "watchRow");
+            var isStackFrame = rowObject instanceof jsdIStackFrame;
+
+            if (typeof(rowValue) == "string" || typeof(rowValue) == "number")
+            {
+                // Functions already have a copy item in their context menu
+                items.push(
+                    "-",
+                    {label: "CopyValue",
+                        command: bindFixed(this.copyProperty, this, row) }
+                );
+            }
+
+            items.push(
+                "-",
+                {label: isWatch ? "EditWatch" : (isStackFrame ? "EditVariable" : "EditProperty"),
+                    command: bindFixed(this.editProperty, this, row) }
+            );
+
+            if (isWatch || (!isStackFrame && !isDOMMember(rowObject, rowName)))
+            {
+                items.push(
+                    {label: isWatch ? "DeleteWatch" : "DeleteProperty",
+                        command: bindFixed(this.deleteProperty, this, row) }
+                );
+            }
+        }
+
+        items.push(
+            "-",
+            {label: "Refresh", command: bindFixed(this.rebuild, this, true) }
+        );
+
+        return items;
+    },
+
+    getEditor: function(target, value)
+    {
+        if (!this.editor)
+            this.editor = new DOMEditor(this.document);
+
+        return this.editor;
+    }/**/
+});
+
+// ************************************************************************************************
+
+// TODO: xxxpedro statusbar
+var updateStatusBar = function(panel)
+{
+    var path = panel.propertyPath;
+    var index = panel.pathIndex;
+
+    var r = [];
+
+    for (var i=0, l=path.length; i<l; i++)
+    {
+        r.push(i==index ? '<a class="fbHover fbButton fbBtnSelected" ' : '<a class="fbHover fbButton" ');
+        r.push('pathIndex=');
+        r.push(i);
+
+        if(isIE6)
+            r.push(' href="javascript:void(0)"');
+
+        r.push('>');
+        r.push(i==0 ? "window" : path[i] || "Object");
+        r.push('</a>');
+
+        if(i < l-1)
+            r.push('<span class="fbStatusSeparator">&gt;</span>');
+    }
+    panel.statusBarNode.innerHTML = r.join("");
+};
+
+
+var DOMMainPanel = Firebug.DOMPanel = function () {};
+
+Firebug.DOMPanel.DirTable = DirTablePlate;
+
+DOMMainPanel.prototype = extend(Firebug.DOMBasePanel.prototype,
+{
+    onClickStatusBar: function(event)
+    {
+        var target = event.srcElement || event.target;
+        var element = getAncestorByClass(target, "fbHover");
+
+        if(element)
+        {
+            var pathIndex = element.getAttribute("pathIndex");
+
+            if(pathIndex)
+            {
+                this.select(this.getPathObject(pathIndex));
+            }
+        }
+    },
+
+    selectRow: function(row, target)
+    {
+        if (!target)
+            target = row.lastChild.firstChild;
+
+        if (!target || !target.repObject)
+            return;
+
+        this.pathToAppend = getPath(row);
+
+        // If the object is inside an array, look up its index
+        var valueBox = row.lastChild.firstChild;
+        if (hasClass(valueBox, "objectBox-array"))
+        {
+            var arrayIndex = FirebugReps.Arr.getItemIndex(target);
+            this.pathToAppend.push(arrayIndex);
+        }
+
+        // Make sure we get a fresh status path for the object, since otherwise
+        // it might find the object in the existing path and not refresh it
+        //Firebug.chrome.clearStatusPath();
+
+        this.select(target.repObject, true);
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onClick: function(event)
+    {
+        var target = event.srcElement || event.target;
+        var repNode = Firebug.getRepNode(target);
+        if (repNode)
+        {
+            var row = getAncestorByClass(target, "memberRow");
+            if (row)
+            {
+                this.selectRow(row, repNode);
+                cancelEvent(event);
+            }
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    name: "DOM",
+    title: "DOM",
+    searchable: true,
+    statusSeparator: ">",
+
+    options: {
+        hasToolButtons: true,
+        hasStatusBar: true
+    },
+
+    create: function()
+    {
+        Firebug.DOMBasePanel.prototype.create.apply(this, arguments);
+
+        this.onClick = bind(this.onClick, this);
+
+        //TODO: xxxpedro
+        this.onClickStatusBar = bind(this.onClickStatusBar, this);
+
+        this.panelNode.style.padding = "0 1px";
+    },
+
+    initialize: function(oldPanelNode)
+    {
+        //this.panelNode.addEventListener("click", this.onClick, false);
+        //dispatch([Firebug.A11yModel], 'onInitializeNode', [this, 'console']);
+
+        Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments);
+
+        addEvent(this.panelNode, "click", this.onClick);
+
+        // TODO: xxxpedro dom
+        this.ishow();
+
+        //TODO: xxxpedro
+        addEvent(this.statusBarNode, "click", this.onClickStatusBar);
+    },
+
+    shutdown: function()
+    {
+        //this.panelNode.removeEventListener("click", this.onClick, false);
+        //dispatch([Firebug.A11yModel], 'onDestroyNode', [this, 'console']);
+
+        removeEvent(this.panelNode, "click", this.onClick);
+
+        Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments);
+    }/*,
+
+    search: function(text, reverse)
+    {
+        if (!text)
+        {
+            delete this.currentSearch;
+            this.highlightRow(null);
+            return false;
+        }
+
+        var row;
+        if (this.currentSearch && text == this.currentSearch.text)
+            row = this.currentSearch.findNext(true, undefined, reverse, Firebug.searchCaseSensitive);
+        else
+        {
+            function findRow(node) { return getAncestorByClass(node, "memberRow"); }
+            this.currentSearch = new TextSearch(this.panelNode, findRow);
+            row = this.currentSearch.find(text, reverse, Firebug.searchCaseSensitive);
+        }
+
+        if (row)
+        {
+            var sel = this.document.defaultView.getSelection();
+            sel.removeAllRanges();
+            sel.addRange(this.currentSearch.range);
+
+            scrollIntoCenterView(row, this.panelNode);
+
+            this.highlightRow(row);
+            dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, row]);
+            return true;
+        }
+        else
+        {
+            dispatch([Firebug.A11yModel], 'onDomSearchMatchFound', [this, text, null]);
+            return false;
+        }
+    }/**/
+});
+
+Firebug.registerPanel(DOMMainPanel);
+
+
+// ************************************************************************************************
+
+
+
+// ************************************************************************************************
+// Local Helpers
+
+var getMembers = function getMembers(object, level)  // we expect object to be user-level object wrapped in security blanket
+{
+    if (!level)
+        level = 0;
+
+    var ordinals = [], userProps = [], userClasses = [], userFuncs = [],
+        domProps = [], domFuncs = [], domConstants = [];
+
+    try
+    {
+        var domMembers = getDOMMembers(object);
+        //var domMembers = {}; // TODO: xxxpedro
+        //var domConstantMap = {};  // TODO: xxxpedro
+
+        if (object.wrappedJSObject)
+            var insecureObject = object.wrappedJSObject;
+        else
+            var insecureObject = object;
+
+        // IE function prototype is not listed in (for..in)
+        if (isIE && isFunction(object))
+            addMember("user", userProps, "prototype", object.prototype, level);
+
+        for (var name in insecureObject)  // enumeration is safe
+        {
+            if (ignoreVars[name] == 1)  // javascript.options.strict says ignoreVars is undefined.
+                continue;
+
+            var val;
+            try
+            {
+                val = insecureObject[name];  // getter is safe
+            }
+            catch (exc)
+            {
+                // Sometimes we get exceptions trying to access certain members
+                if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
+                    FBTrace.sysout("dom.getMembers cannot access "+name, exc);
+            }
+
+            var ordinal = parseInt(name);
+            if (ordinal || ordinal == 0)
+            {
+                addMember("ordinal", ordinals, name, val, level);
+            }
+            else if (isFunction(val))
+            {
+                if (isClassFunction(val) && !(name in domMembers))
+                    addMember("userClass", userClasses, name, val, level);
+                else if (name in domMembers)
+                    addMember("domFunction", domFuncs, name, val, level, domMembers[name]);
+                else
+                    addMember("userFunction", userFuncs, name, val, level);
+            }
+            else
+            {
+                //TODO: xxxpedro
+                /*
+                var getterFunction = insecureObject.__lookupGetter__(name),
+                    setterFunction = insecureObject.__lookupSetter__(name),
+                    prefix = "";
+
+                if(getterFunction && !setterFunction)
+                    prefix = "get ";
+                /**/
+
+                var prefix = "";
+
+                if (name in domMembers && !(name in domConstantMap))
+                    addMember("dom", domProps, (prefix+name), val, level, domMembers[name]);
+                else if (name in domConstantMap)
+                    addMember("dom", domConstants, (prefix+name), val, level);
+                else
+                    addMember("user", userProps, (prefix+name), val, level);
+            }
+        }
+    }
+    catch (exc)
+    {
+        // Sometimes we get exceptions just from trying to iterate the members
+        // of certain objects, like StorageList, but don't let that gum up the works
+        throw exc;
+        if (FBTrace.DBG_ERRORS && FBTrace.DBG_DOM)
+            FBTrace.sysout("dom.getMembers FAILS: ", exc);
+        //throw exc;
+    }
+
+    function sortName(a, b) { return a.name > b.name ? 1 : -1; }
+    function sortOrder(a, b) { return a.order > b.order ? 1 : -1; }
+
+    var members = [];
+
+    members.push.apply(members, ordinals);
+
+    Firebug.showUserProps = true; // TODO: xxxpedro
+    Firebug.showUserFuncs = true; // TODO: xxxpedro
+    Firebug.showDOMProps = true;
+    Firebug.showDOMFuncs = true;
+    Firebug.showDOMConstants = true;
+
+    if (Firebug.showUserProps)
+    {
+        userProps.sort(sortName);
+        members.push.apply(members, userProps);
+    }
+
+    if (Firebug.showUserFuncs)
+    {
+        userClasses.sort(sortName);
+        members.push.apply(members, userClasses);
+
+        userFuncs.sort(sortName);
+        members.push.apply(members, userFuncs);
+    }
+
+    if (Firebug.showDOMProps)
+    {
+        domProps.sort(sortName);
+        members.push.apply(members, domProps);
+    }
+
+    if (Firebug.showDOMFuncs)
+    {
+        domFuncs.sort(sortName);
+        members.push.apply(members, domFuncs);
+    }
+
+    if (Firebug.showDOMConstants)
+        members.push.apply(members, domConstants);
+
+    return members;
+};
+
+function expandMembers(members, toggles, offset, level)  // recursion starts with offset=0, level=0
+{
+    var expanded = 0;
+    for (var i = offset; i < members.length; ++i)
+    {
+        var member = members[i];
+        if (member.level > level)
+            break;
+
+        if ( toggles.hasOwnProperty(member.name) )
+        {
+            member.open = "opened";  // member.level <= level && member.name in toggles.
+
+            var newMembers = getMembers(member.value, level+1);  // sets newMembers.level to level+1
+
+            var args = [i+1, 0];
+            args.push.apply(args, newMembers);
+            members.splice.apply(members, args);
+
+            /*
+            if (FBTrace.DBG_DOM)
+            {
+                FBTrace.sysout("expandMembers member.name", member.name);
+                FBTrace.sysout("expandMembers toggles", toggles);
+                FBTrace.sysout("expandMembers toggles[member.name]", toggles[member.name]);
+                FBTrace.sysout("dom.expandedMembers level: "+level+" member", member);
+            }
+            /**/
+
+            expanded += newMembers.length;
+            i += newMembers.length + expandMembers(members, toggles[member.name], i+1, level+1);
+        }
+    }
+
+    return expanded;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+
+function isClassFunction(fn)
+{
+    try
+    {
+        for (var name in fn.prototype)
+            return true;
+    } catch (exc) {}
+    return false;
+}
+
+// FIXME: xxxpedro This function is already defined in Lib. If we keep this definition here, it
+// will crash IE9 when not running the IE Developer Tool with JavaScript Debugging enabled!!!
+// Check if this function is in fact defined in Firebug for Firefox. If so, we should remove
+// this from here. The only difference of this function is the IE hack to show up the prototype
+// of functions, but Firebug no longer shows the prototype for simple functions.
+//var hasProperties = function hasProperties(ob)
+//{
+//    try
+//    {
+//        for (var name in ob)
+//            return true;
+//    } catch (exc) {}
+//
+//    // IE function prototype is not listed in (for..in)
+//    if (isFunction(ob)) return true;
+//
+//    return false;
+//};
+
+FBL.ErrorCopy = function(message)
+{
+    this.message = message;
+};
+
+var addMember = function addMember(type, props, name, value, level, order)
+{
+    var rep = Firebug.getRep(value);    // do this first in case a call to instanceof reveals contents
+    var tag = rep.shortTag ? rep.shortTag : rep.tag;
+
+    var ErrorCopy = function(){}; //TODO: xxxpedro
+
+    var valueType = typeof(value);
+    var hasChildren = hasProperties(value) && !(value instanceof ErrorCopy) &&
+        (isFunction(value) || (valueType == "object" && value != null)
+        || (valueType == "string" && value.length > Firebug.stringCropLength));
+
+    props.push({
+        name: name,
+        value: value,
+        type: type,
+        rowClass: "memberRow-"+type,
+        open: "",
+        order: order,
+        level: level,
+        indent: level*16,
+        hasChildren: hasChildren,
+        tag: tag
+    });
+};
+
+var getWatchRowIndex = function getWatchRowIndex(row)
+{
+    var index = -1;
+    for (; row && hasClass(row, "watchRow"); row = row.previousSibling)
+        ++index;
+    return index;
+};
+
+var getRowName = function getRowName(row)
+{
+    var node = row.firstChild;
+    return node.textContent ? node.textContent : node.innerText;
+};
+
+var getRowValue = function getRowValue(row)
+{
+    return row.lastChild.firstChild.repObject;
+};
+
+var getRowOwnerObject = function getRowOwnerObject(row)
+{
+    var parentRow = getParentRow(row);
+    if (parentRow)
+        return getRowValue(parentRow);
+};
+
+var getParentRow = function getParentRow(row)
+{
+    var level = parseInt(row.getAttribute("level"))-1;
+    for (row = row.previousSibling; row; row = row.previousSibling)
+    {
+        if (parseInt(row.getAttribute("level")) == level)
+            return row;
+    }
+};
+
+var getPath = function getPath(row)
+{
+    var name = getRowName(row);
+    var path = [name];
+
+    var level = parseInt(row.getAttribute("level"))-1;
+    for (row = row.previousSibling; row; row = row.previousSibling)
+    {
+        if (parseInt(row.getAttribute("level")) == level)
+        {
+            var name = getRowName(row);
+            path.splice(0, 0, name);
+
+            --level;
+        }
+    }
+
+    return path;
+};
+
+// ************************************************************************************************
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+
+// ************************************************************************************************
+// DOM Module
+
+Firebug.DOM = extend(Firebug.Module,
+{
+    getPanel: function()
+    {
+        return Firebug.chrome ? Firebug.chrome.getPanel("DOM") : null;
+    }
+});
+
+Firebug.registerModule(Firebug.DOM);
+
+
+// ************************************************************************************************
+// DOM Panel
+
+var lastHighlightedObject;
+
+function DOMSidePanel(){};
+
+DOMSidePanel.prototype = extend(Firebug.DOMBasePanel.prototype,
+{
+    selectRow: function(row, target)
+    {
+        if (!target)
+            target = row.lastChild.firstChild;
+
+        if (!target || !target.repObject)
+            return;
+
+        this.pathToAppend = getPath(row);
+
+        // If the object is inside an array, look up its index
+        var valueBox = row.lastChild.firstChild;
+        if (hasClass(valueBox, "objectBox-array"))
+        {
+            var arrayIndex = FirebugReps.Arr.getItemIndex(target);
+            this.pathToAppend.push(arrayIndex);
+        }
+
+        // Make sure we get a fresh status path for the object, since otherwise
+        // it might find the object in the existing path and not refresh it
+        //Firebug.chrome.clearStatusPath();
+
+        var object = target.repObject;
+
+        if (instanceOf(object, "Element"))
+        {
+            Firebug.HTML.selectTreeNode(ElementCache(object));
+        }
+        else
+        {
+            Firebug.chrome.selectPanel("DOM");
+            Firebug.chrome.getPanel("DOM").select(object, true);
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+    onClick: function(event)
+    {
+        /*
+        var target = event.srcElement || event.target;
+
+        var object = getAncestorByClass(target, "objectLink");
+        object = object ? object.repObject : null;
+
+        if(!object) return;
+
+        if (instanceOf(object, "Element"))
+        {
+            Firebug.HTML.selectTreeNode(ElementCache(object));
+        }
+        else
+        {
+            Firebug.chrome.selectPanel("DOM");
+            Firebug.chrome.getPanel("DOM").select(object, true);
+        }
+        /**/
+
+
+        var target = event.srcElement || event.target;
+        var repNode = Firebug.getRepNode(target);
+        if (repNode)
+        {
+            var row = getAncestorByClass(target, "memberRow");
+            if (row)
+            {
+                this.selectRow(row, repNode);
+                cancelEvent(event);
+            }
+        }
+        /**/
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // extends Panel
+
+    name: "DOMSidePanel",
+    parentPanel: "HTML",
+    title: "DOM",
+
+    options: {
+        hasToolButtons: true
+    },
+
+    isInitialized: false,
+
+    create: function()
+    {
+        Firebug.DOMBasePanel.prototype.create.apply(this, arguments);
+
+        this.onClick = bind(this.onClick, this);
+    },
+
+    initialize: function(){
+        Firebug.DOMBasePanel.prototype.initialize.apply(this, arguments);
+
+        addEvent(this.panelNode, "click", this.onClick);
+
+        // TODO: xxxpedro css2
+        var selection = ElementCache.get(Firebug.context.persistedState.selectedHTMLElementId);
+        if (selection)
+            this.select(selection, true);
+    },
+
+    shutdown: function()
+    {
+        removeEvent(this.panelNode, "click", this.onClick);
+
+        Firebug.DOMBasePanel.prototype.shutdown.apply(this, arguments);
+    },
+
+    reattach: function(oldChrome)
+    {
+        //this.isInitialized = oldChrome.getPanel("DOM").isInitialized;
+        this.toggles = oldChrome.getPanel("DOMSidePanel").toggles;
+    }
+
+});
+
+Firebug.registerPanel(DOMSidePanel);
+
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.FBTrace = {};
+
+(function() {
+// ************************************************************************************************
+
+var traceOptions = {
+    DBG_TIMESTAMP: 1,
+    DBG_INITIALIZE: 1,
+    DBG_CHROME: 1,
+    DBG_ERRORS: 1,
+    DBG_DISPATCH: 1,
+    DBG_CSS: 1
+};
+
+this.module = null;
+
+this.initialize = function()
+{
+    if (!this.messageQueue)
+        this.messageQueue = [];
+
+    for (var name in traceOptions)
+        this[name] = traceOptions[name];
+};
+
+// ************************************************************************************************
+// FBTrace API
+
+this.sysout = function()
+{
+    return this.logFormatted(arguments, "");
+};
+
+this.dumpProperties = function(title, object)
+{
+    return this.logFormatted("dumpProperties() not supported.", "warning");
+};
+
+this.dumpStack = function()
+{
+    return this.logFormatted("dumpStack() not supported.", "warning");
+};
+
+this.flush = function(module)
+{
+    this.module = module;
+
+    var queue = this.messageQueue;
+    this.messageQueue = [];
+
+    for (var i = 0; i < queue.length; ++i)
+        this.writeMessage(queue[i][0], queue[i][1], queue[i][2]);
+};
+
+this.getPanel = function()
+{
+    return this.module ? this.module.getPanel() : null;
+};
+
+//*************************************************************************************************
+
+this.logFormatted = function(objects, className)
+{
+    var html = this.DBG_TIMESTAMP ? [getTimestamp(), " | "] : [];
+    var length = objects.length;
+
+    for (var i = 0; i < length; ++i)
+    {
+        appendText(" ", html);
+
+        var object = objects[i];
+
+        if (i == 0)
+        {
+            html.push("<b>");
+            appendText(object, html);
+            html.push("</b>");
+        }
+        else
+            appendText(object, html);
+    }
+
+    return this.logRow(html, className);
+};
+
+this.logRow = function(message, className)
+{
+    var panel = this.getPanel();
+
+    if (panel && panel.panelNode)
+        this.writeMessage(message, className);
+    else
+    {
+        this.messageQueue.push([message, className]);
+    }
+
+    return this.LOG_COMMAND;
+};
+
+this.writeMessage = function(message, className)
+{
+    var container = this.getPanel().containerNode;
+    var isScrolledToBottom =
+        container.scrollTop + container.offsetHeight >= container.scrollHeight;
+
+    this.writeRow.call(this, message, className);
+
+    if (isScrolledToBottom)
+        container.scrollTop = container.scrollHeight - container.offsetHeight;
+};
+
+this.appendRow = function(row)
+{
+    var container = this.getPanel().panelNode;
+    container.appendChild(row);
+};
+
+this.writeRow = function(message, className)
+{
+    var row = this.getPanel().panelNode.ownerDocument.createElement("div");
+    row.className = "logRow" + (className ? " logRow-"+className : "");
+    row.innerHTML = message.join("");
+    this.appendRow(row);
+};
+
+//*************************************************************************************************
+
+function appendText(object, html)
+{
+    html.push(escapeHTML(objectToString(object)));
+};
+
+function getTimestamp()
+{
+    var now = new Date();
+    var ms = "" + (now.getMilliseconds() / 1000).toFixed(3);
+    ms = ms.substr(2);
+
+    return now.toLocaleTimeString() + "." + ms;
+};
+
+//*************************************************************************************************
+
+var HTMLtoEntity =
+{
+    "<": "&lt;",
+    ">": "&gt;",
+    "&": "&amp;",
+    "'": "&#39;",
+    '"': "&quot;"
+};
+
+function replaceChars(ch)
+{
+    return HTMLtoEntity[ch];
+};
+
+function escapeHTML(value)
+{
+    return (value+"").replace(/[<>&"']/g, replaceChars);
+};
+
+//*************************************************************************************************
+
+function objectToString(object)
+{
+    try
+    {
+        return object+"";
+    }
+    catch (exc)
+    {
+        return null;
+    }
+};
+
+// ************************************************************************************************
+}).apply(FBL.FBTrace);
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// If application isn't in trace mode, the FBTrace panel won't be loaded
+if (!Env.Options.enableTrace) return;
+
+// ************************************************************************************************
+// FBTrace Module
+
+Firebug.Trace = extend(Firebug.Module,
+{
+    getPanel: function()
+    {
+        return Firebug.chrome ? Firebug.chrome.getPanel("Trace") : null;
+    },
+
+    clear: function()
+    {
+        this.getPanel().panelNode.innerHTML = "";
+    }
+});
+
+Firebug.registerModule(Firebug.Trace);
+
+
+// ************************************************************************************************
+// FBTrace Panel
+
+function TracePanel(){};
+
+TracePanel.prototype = extend(Firebug.Panel,
+{
+    name: "Trace",
+    title: "Trace",
+
+    options: {
+        hasToolButtons: true,
+        innerHTMLSync: true
+    },
+
+    create: function(){
+        Firebug.Panel.create.apply(this, arguments);
+
+        this.clearButton = new Button({
+            caption: "Clear",
+            title: "Clear FBTrace logs",
+            owner: Firebug.Trace,
+            onClick: Firebug.Trace.clear
+        });
+    },
+
+    initialize: function(){
+        Firebug.Panel.initialize.apply(this, arguments);
+
+        this.clearButton.initialize();
+    },
+
+    shutdown: function()
+    {
+        this.clearButton.shutdown();
+
+        Firebug.Panel.shutdown.apply(this, arguments);
+    }
+
+});
+
+Firebug.registerPanel(TracePanel);
+
+// ************************************************************************************************
+}});
+
+/* See license.txt for terms of usage */
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+// ************************************************************************************************
+// Globals
+
+var modules = [];
+var panelTypes = [];
+var panelTypeMap = {};
+
+var parentPanelMap = {};
+
+
+var registerModule = Firebug.registerModule;
+var registerPanel = Firebug.registerPanel;
+
+// ************************************************************************************************
+append(Firebug,
+{
+    extend: function(fn)
+    {
+        if (Firebug.chrome && Firebug.chrome.addPanel)
+        {
+            var namespace = ns(fn);
+            fn.call(namespace, FBL);
+        }
+        else
+        {
+            setTimeout(function(){Firebug.extend(fn);},100);
+        }
+    },
+
+    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+    // Registration
+
+    registerModule: function()
+    {
+        registerModule.apply(Firebug, arguments);
+
+        modules.push.apply(modules, arguments);
+
+        dispatch(modules, "initialize", []);
+
+        if (FBTrace.DBG_INITIALIZE) FBTrace.sysout("Firebug.registerModule");
+    },
+
+    registerPanel: function()
+    {
+        registerPanel.apply(Firebug, arguments);
+
+        panelTypes.push.apply(panelTypes, arguments);
+
+        for (var i = 0, panelType; panelType = arguments[i]; ++i)
+        {
+            // TODO: xxxpedro investigate why Dev Panel throws an error
+            if (panelType.prototype.name == "Dev") continue;
+
+            panelTypeMap[panelType.prototype.name] = arguments[i];
+
+            var parentPanelName = panelType.prototype.parentPanel;
+            if (parentPanelName)
+            {
+                parentPanelMap[parentPanelName] = 1;
+            }
+            else
+            {
+                var panelName = panelType.prototype.name;
+                var chrome = Firebug.chrome;
+                chrome.addPanel(panelName);
+
+                // tab click handler
+                var onTabClick = function onTabClick()
+                {
+                    chrome.selectPanel(panelName);
+                    return false;
+                };
+
+                chrome.addController([chrome.panelMap[panelName].tabNode, "mousedown", onTabClick]);
+            }
+        }
+
+        if (FBTrace.DBG_INITIALIZE)
+            for (var i = 0; i < arguments.length; ++i)
+                FBTrace.sysout("Firebug.registerPanel", arguments[i].prototype.name);
+    }
+
+});
+
+
+
+
+// ************************************************************************************************
+}});
+
+FBL.ns(function() { with (FBL) {
+// ************************************************************************************************
+
+FirebugChrome.Skin =
+{
+    CSS: '.obscured{left:-999999px !important;}.collapsed{display:none;}[collapsed="true"]{display:none;}#fbCSS{padding:0 !important;}.cssPropDisable{float:left;display:block;width:2em;cursor:default;}.infoTip{z-index:2147483647;position:fixed;padding:2px 3px;border:1px solid #CBE087;background:LightYellow;font-family:Monaco,monospace;color:#000000;display:none;white-space:nowrap;pointer-events:none;}.infoTip[active="true"]{display:block;}.infoTipLoading{width:16px;height:16px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/loading_16.gif) no-repeat;}.infoTipImageBox{font-size:11px;min-width:100px;text-align:center;}.infoTipCaption{font-size:11px;font:Monaco,monospace;}.infoTipLoading > .infoTipImage,.infoTipLoading > .infoTipCaption{display:none;}h1.groupHeader{padding:2px 4px;margin:0 0 4px 0;border-top:1px solid #CCCCCC;border-bottom:1px solid #CCCCCC;background:#eee url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x;font-size:11px;font-weight:bold;_position:relative;}.inlineEditor,.fixedWidthEditor{z-index:2147483647;position:absolute;display:none;}.inlineEditor{margin-left:-6px;margin-top:-3px;}.textEditorInner,.fixedWidthEditor{margin:0 0 0 0 !important;padding:0;border:none !important;font:inherit;text-decoration:inherit;background-color:#FFFFFF;}.fixedWidthEditor{border-top:1px solid #888888 !important;border-bottom:1px solid #888888 !important;}.textEditorInner{position:relative;top:-7px;left:-5px;outline:none;resize:none;}.textEditorInner1{padding-left:11px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.png) repeat-y;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.gif) repeat-y;_overflow:hidden;}.textEditorInner2{position:relative;padding-right:2px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.png) repeat-y 100% 0;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorBorders.gif) repeat-y 100% 0;_position:fixed;}.textEditorTop1{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 100% 0;margin-left:11px;height:10px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 100% 0;_overflow:hidden;}.textEditorTop2{position:relative;left:-11px;width:11px;height:10px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat;}.textEditorBottom1{position:relative;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 100% 100%;margin-left:11px;height:12px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 100% 100%;}.textEditorBottom2{position:relative;left:-11px;width:11px;height:12px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.png) no-repeat 0 100%;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/textEditorCorners.gif) no-repeat 0 100%;}.panelNode-css{overflow-x:hidden;}.cssSheet > .insertBefore{height:1.5em;}.cssRule{position:relative;margin:0;padding:1em 0 0 6px;font-family:Monaco,monospace;color:#000000;}.cssRule:first-child{padding-top:6px;}.cssElementRuleContainer{position:relative;}.cssHead{padding-right:150px;}.cssProp{}.cssPropName{color:DarkGreen;}.cssPropValue{margin-left:8px;color:DarkBlue;}.cssOverridden span{text-decoration:line-through;}.cssInheritedRule{}.cssInheritLabel{margin-right:0.5em;font-weight:bold;}.cssRule .objectLink-sourceLink{top:0;}.cssProp.editGroup:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disable.png) no-repeat 2px 1px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disable.gif) no-repeat 2px 1px;}.cssProp.editGroup.editing{background:none;}.cssProp.disabledStyle{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disableHover.png) no-repeat 2px 1px;_background:url(https://getfirebug.com/releases/lite/latest/skin/xp/disableHover.gif) no-repeat 2px 1px;opacity:1;color:#CCCCCC;}.disabledStyle .cssPropName,.disabledStyle .cssPropValue{color:#CCCCCC;}.cssPropValue.editing + .cssSemi,.inlineExpander + .cssSemi{display:none;}.cssPropValue.editing{white-space:nowrap;}.stylePropName{font-weight:bold;padding:0 4px 4px 4px;width:50%;}.stylePropValue{width:50%;}.panelNode-net{overflow-x:hidden;}.netTable{width:100%;}.hideCategory-undefined .category-undefined,.hideCategory-html .category-html,.hideCategory-css .category-css,.hideCategory-js .category-js,.hideCategory-image .category-image,.hideCategory-xhr .category-xhr,.hideCategory-flash .category-flash,.hideCategory-txt .category-txt,.hideCategory-bin .category-bin{display:none;}.netHeadRow{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/group.gif) repeat-x #FFFFFF;}.netHeadCol{border-bottom:1px solid #CCCCCC;padding:2px 4px 2px 18px;font-weight:bold;}.netHeadLabel{white-space:nowrap;overflow:hidden;}.netHeaderRow{height:16px;}.netHeaderCell{cursor:pointer;-moz-user-select:none;border-bottom:1px solid #9C9C9C;padding:0 !important;font-weight:bold;background:#BBBBBB url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeader.gif) repeat-x;white-space:nowrap;}.netHeaderRow > .netHeaderCell:first-child > .netHeaderCellBox{padding:2px 14px 2px 18px;}.netHeaderCellBox{padding:2px 14px 2px 10px;border-left:1px solid #D9D9D9;border-right:1px solid #9C9C9C;}.netHeaderCell:hover:active{background:#959595 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderActive.gif) repeat-x;}.netHeaderSorted{background:#7D93B2 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderSorted.gif) repeat-x;}.netHeaderSorted > .netHeaderCellBox{border-right-color:#6B7C93;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/arrowDown.png) no-repeat right;}.netHeaderSorted.sortedAscending > .netHeaderCellBox{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/arrowUp.png);}.netHeaderSorted:hover:active{background:#536B90 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/tableHeaderSortedActive.gif) repeat-x;}.panelNode-net .netRowHeader{display:block;}.netRowHeader{cursor:pointer;display:none;height:15px;margin-right:0 !important;}.netRow .netRowHeader{background-position:5px 1px;}.netRow[breakpoint="true"] .netRowHeader{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/breakpoint.png);}.netRow[breakpoint="true"][disabledBreakpoint="true"] .netRowHeader{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/breakpointDisabled.png);}.netRow.category-xhr:hover .netRowHeader{background-color:#F6F6F6;}#netBreakpointBar{max-width:38px;}#netHrefCol > .netHeaderCellBox{border-left:0px;}.netRow .netRowHeader{width:3px;}.netInfoRow .netRowHeader{display:table-cell;}.netTable[hiddenCols~=netHrefCol] TD[id="netHrefCol"],.netTable[hiddenCols~=netHrefCol] TD.netHrefCol,.netTable[hiddenCols~=netStatusCol] TD[id="netStatusCol"],.netTable[hiddenCols~=netStatusCol] TD.netStatusCol,.netTable[hiddenCols~=netDomainCol] TD[id="netDomainCol"],.netTable[hiddenCols~=netDomainCol] TD.netDomainCol,.netTable[hiddenCols~=netSizeCol] TD[id="netSizeCol"],.netTable[hiddenCols~=netSizeCol] TD.netSizeCol,.netTable[hiddenCols~=netTimeCol] TD[id="netTimeCol"],.netTable[hiddenCols~=netTimeCol] TD.netTimeCol{display:none;}.netRow{background:LightYellow;}.netRow.loaded{background:#FFFFFF;}.netRow.loaded:hover{background:#EFEFEF;}.netCol{padding:0;vertical-align:top;border-bottom:1px solid #EFEFEF;white-space:nowrap;height:17px;}.netLabel{width:100%;}.netStatusCol{padding-left:10px;color:rgb(128,128,128);}.responseError > .netStatusCol{color:red;}.netDomainCol{padding-left:5px;}.netSizeCol{text-align:right;padding-right:10px;}.netHrefLabel{-moz-box-sizing:padding-box;overflow:hidden;z-index:10;position:absolute;padding-left:18px;padding-top:1px;max-width:15%;font-weight:bold;}.netFullHrefLabel{display:none;-moz-user-select:none;padding-right:10px;padding-bottom:3px;max-width:100%;background:#FFFFFF;z-index:200;}.netHrefCol:hover > .netFullHrefLabel{display:block;}.netRow.loaded:hover .netCol > .netFullHrefLabel{background-color:#EFEFEF;}.useA11y .a11yShowFullLabel{display:block;background-image:none !important;border:1px solid #CBE087;background-color:LightYellow;font-family:Monaco,monospace;color:#000000;font-size:10px;z-index:2147483647;}.netSizeLabel{padding-left:6px;}.netStatusLabel,.netDomainLabel,.netSizeLabel,.netBar{padding:1px 0 2px 0 !important;}.responseError{color:red;}.hasHeaders .netHrefLabel:hover{cursor:pointer;color:blue;text-decoration:underline;}.netLoadingIcon{position:absolute;border:0;margin-left:14px;width:16px;height:16px;background:transparent no-repeat 0 0;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/loading_16.gif);display:inline-block;}.loaded .netLoadingIcon{display:none;}.netBar,.netSummaryBar{position:relative;border-right:50px solid transparent;}.netResolvingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarResolving.gif) repeat-x;z-index:60;}.netConnectingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarConnecting.gif) repeat-x;z-index:50;}.netBlockingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarWaiting.gif) repeat-x;z-index:40;}.netSendingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarSending.gif) repeat-x;z-index:30;}.netWaitingBar{position:absolute;left:0;top:0;bottom:0;background:#FFFFFF url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarResponded.gif) repeat-x;z-index:20;min-width:1px;}.netReceivingBar{position:absolute;left:0;top:0;bottom:0;background:#38D63B url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarLoading.gif) repeat-x;z-index:10;}.netWindowLoadBar,.netContentLoadBar{position:absolute;left:0;top:0;bottom:0;width:1px;background-color:red;z-index:70;opacity:0.5;display:none;margin-bottom:-1px;}.netContentLoadBar{background-color:Blue;}.netTimeLabel{-moz-box-sizing:padding-box;position:absolute;top:1px;left:100%;padding-left:6px;color:#444444;min-width:16px;}.loaded .netReceivingBar,.loaded.netReceivingBar{background:#B6B6B6 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarLoaded.gif) repeat-x;border-color:#B6B6B6;}.fromCache .netReceivingBar,.fromCache.netReceivingBar{background:#D6D6D6 url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/netBarCached.gif) repeat-x;border-color:#D6D6D6;}.netSummaryRow .netTimeLabel,.loaded .netTimeLabel{background:transparent;}.timeInfoTip{width:150px; height:40px}.timeInfoTipBar,.timeInfoTipEventBar{position:relative;display:block;margin:0;opacity:1;height:15px;width:4px;}.timeInfoTipEventBar{width:1px !important;}.timeInfoTipCell.startTime{padding-right:8px;}.timeInfoTipCell.elapsedTime{text-align:right;padding-right:8px;}.sizeInfoLabelCol{font-weight:bold;padding-right:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;}.sizeInfoSizeCol{font-weight:bold;}.sizeInfoDetailCol{color:gray;text-align:right;}.sizeInfoDescCol{font-style:italic;}.netSummaryRow .netReceivingBar{background:#BBBBBB;border:none;}.netSummaryLabel{color:#222222;}.netSummaryRow{background:#BBBBBB !important;font-weight:bold;}.netSummaryRow .netBar{border-right-color:#BBBBBB;}.netSummaryRow > .netCol{border-top:1px solid #999999;border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;padding-top:1px;padding-bottom:2px;}.netSummaryRow > .netHrefCol:hover{background:transparent !important;}.netCountLabel{padding-left:18px;}.netTotalSizeCol{text-align:right;padding-right:10px;}.netTotalTimeCol{text-align:right;}.netCacheSizeLabel{position:absolute;z-index:1000;left:0;top:0;}.netLimitRow{background:rgb(255,255,225) !important;font-weight:normal;color:black;font-weight:normal;}.netLimitLabel{padding-left:18px;}.netLimitRow > .netCol{border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;vertical-align:middle !important;padding-top:2px;padding-bottom:2px;}.netLimitButton{font-size:11px;padding-top:1px;padding-bottom:1px;}.netInfoCol{border-top:1px solid #EEEEEE;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/group.gif) repeat-x #FFFFFF;}.netInfoBody{margin:10px 0 4px 10px;}.netInfoTabs{position:relative;padding-left:17px;}.netInfoTab{position:relative;top:-3px;margin-top:10px;padding:4px 6px;border:1px solid transparent;border-bottom:none;_border:none;font-weight:bold;color:#565656;cursor:pointer;}.netInfoTabSelected{cursor:default !important;border:1px solid #D7D7D7 !important;border-bottom:none !important;-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;background-color:#FFFFFF;}.logRow-netInfo.error .netInfoTitle{color:red;}.logRow-netInfo.loading .netInfoResponseText{font-style:italic;color:#888888;}.loading .netInfoResponseHeadersTitle{display:none;}.netInfoResponseSizeLimit{font-family:Lucida Grande,Tahoma,sans-serif;padding-top:10px;font-size:11px;}.netInfoText{display:none;margin:0;border:1px solid #D7D7D7;border-right:none;padding:8px;background-color:#FFFFFF;font-family:Monaco,monospace;white-space:pre-wrap;}.netInfoTextSelected{display:block;}.netInfoParamName{padding-right:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;vertical-align:top;text-align:right;white-space:nowrap;}.netInfoPostText .netInfoParamName{width:1px;}.netInfoParamValue{width:100%;}.netInfoHeadersText,.netInfoPostText,.netInfoPutText{padding-top:0;}.netInfoHeadersGroup,.netInfoPostParams,.netInfoPostSource{margin-bottom:4px;border-bottom:1px solid #D7D7D7;padding-top:8px;padding-bottom:2px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#565656;}.netInfoPostParamsTable,.netInfoPostPartsTable,.netInfoPostJSONTable,.netInfoPostXMLTable,.netInfoPostSourceTable{margin-bottom:10px;width:100%;}.netInfoPostContentType{color:#bdbdbd;padding-left:50px;font-weight:normal;}.netInfoHtmlPreview{border:0;width:100%;height:100%;}.netHeadersViewSource{color:#bdbdbd;margin-left:200px;font-weight:normal;}.netHeadersViewSource:hover{color:blue;cursor:pointer;}.netActivationRow,.netPageSeparatorRow{background:rgb(229,229,229) !important;font-weight:normal;color:black;}.netActivationLabel{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/chrome://firebug/skin/infoIcon.png) no-repeat 3px 2px;padding-left:22px;}.netPageSeparatorRow{height:5px !important;}.netPageSeparatorLabel{padding-left:22px;height:5px !important;}.netPageRow{background-color:rgb(255,255,255);}.netPageRow:hover{background:#EFEFEF;}.netPageLabel{padding:1px 0 2px 18px !important;font-weight:bold;}.netActivationRow > .netCol{border-bottom:2px solid;-moz-border-bottom-colors:#EFEFEF #999999;padding-top:2px;padding-bottom:3px;}.twisty,.logRow-errorMessage > .hasTwisty > .errorTitle,.logRow-log > .objectBox-array.hasTwisty,.logRow-spy .spyHead .spyTitle,.logGroup > .logRow,.memberRow.hasChildren > .memberLabelCell > .memberLabel,.hasHeaders .netHrefLabel,.netPageRow > .netCol > .netPageTitle{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);background-repeat:no-repeat;background-position:2px 2px;min-height:12px;}.logRow-errorMessage > .hasTwisty.opened > .errorTitle,.logRow-log > .objectBox-array.hasTwisty.opened,.logRow-spy.opened .spyHead .spyTitle,.logGroup.opened > .logRow,.memberRow.hasChildren.opened > .memberLabelCell > .memberLabel,.nodeBox.highlightOpen > .nodeLabel > .twisty,.nodeBox.open > .nodeLabel > .twisty,.netRow.opened > .netCol > .netHrefLabel,.netPageRow.opened > .netCol > .netPageTitle{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);}.twisty{background-position:4px 4px;}* html .logRow-spy .spyHead .spyTitle,* html .logGroup .logGroupLabel,* html .hasChildren .memberLabelCell .memberLabel,* html .hasHeaders .netHrefLabel{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);background-repeat:no-repeat;background-position:2px 2px;}* html .opened .spyHead .spyTitle,* html .opened .logGroupLabel,* html .opened .memberLabelCell .memberLabel{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);background-repeat:no-repeat;background-position:2px 2px;}.panelNode-console{overflow-x:hidden;}.objectLink{text-decoration:none;}.objectLink:hover{cursor:pointer;text-decoration:underline;}.logRow{position:relative;margin:0;border-bottom:1px solid #D7D7D7;padding:2px 4px 1px 6px;background-color:#FFFFFF;overflow:hidden !important;}.useA11y .logRow:focus{border-bottom:1px solid #000000 !important;outline:none !important;background-color:#FFFFAD !important;}.useA11y .logRow:focus a.objectLink-sourceLink{background-color:#FFFFAD;}.useA11y .a11yFocus:focus,.useA11y .objectBox:focus{outline:2px solid #FF9933;background-color:#FFFFAD;}.useA11y .objectBox-null:focus,.useA11y .objectBox-undefined:focus{background-color:#888888 !important;}.useA11y .logGroup.opened > .logRow{border-bottom:1px solid #ffffff;}.logGroup{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x #FFFFFF;padding:0 !important;border:none !important;}.logGroupBody{display:none;margin-left:16px;border-left:1px solid #D7D7D7;border-top:1px solid #D7D7D7;background:#FFFFFF;}.logGroup > .logRow{background-color:transparent !important;font-weight:bold;}.logGroup.opened > .logRow{border-bottom:none;}.logGroup.opened > .logGroupBody{display:block;}.logRow-command > .objectBox-text{font-family:Monaco,monospace;color:#0000FF;white-space:pre-wrap;}.logRow-info,.logRow-warn,.logRow-error,.logRow-assert,.logRow-warningMessage,.logRow-errorMessage{padding-left:22px;background-repeat:no-repeat;background-position:4px 2px;}.logRow-assert,.logRow-warningMessage,.logRow-errorMessage{padding-top:0;padding-bottom:0;}.logRow-info,.logRow-info .objectLink-sourceLink{background-color:#FFFFFF;}.logRow-warn,.logRow-warningMessage,.logRow-warn .objectLink-sourceLink,.logRow-warningMessage .objectLink-sourceLink{background-color:cyan;}.logRow-error,.logRow-assert,.logRow-errorMessage,.logRow-error .objectLink-sourceLink,.logRow-errorMessage .objectLink-sourceLink{background-color:LightYellow;}.logRow-error,.logRow-assert,.logRow-errorMessage{color:#FF0000;}.logRow-info{}.logRow-warn,.logRow-warningMessage{}.logRow-error,.logRow-assert,.logRow-errorMessage{}.objectBox-string,.objectBox-text,.objectBox-number,.objectLink-element,.objectLink-textNode,.objectLink-function,.objectBox-stackTrace,.objectLink-profile{font-family:Monaco,monospace;}.objectBox-string,.objectBox-text,.objectLink-textNode{white-space:pre-wrap;}.objectBox-number,.objectLink-styleRule,.objectLink-element,.objectLink-textNode{color:#000088;}.objectBox-string{color:#FF0000;}.objectLink-function,.objectBox-stackTrace,.objectLink-profile{color:DarkGreen;}.objectBox-null,.objectBox-undefined{padding:0 2px;border:1px solid #666666;background-color:#888888;color:#FFFFFF;}.objectBox-exception{padding:0 2px 0 18px;color:red;}.objectLink-sourceLink{position:absolute;right:4px;top:2px;padding-left:8px;font-family:Lucida Grande,sans-serif;font-weight:bold;color:#0000FF;}.errorTitle{margin-top:0px;margin-bottom:1px;padding-top:2px;padding-bottom:2px;}.errorTrace{margin-left:17px;}.errorSourceBox{margin:2px 0;}.errorSource-none{display:none;}.errorSource-syntax > .errorBreak{visibility:hidden;}.errorSource{cursor:pointer;font-family:Monaco,monospace;color:DarkGreen;}.errorSource:hover{text-decoration:underline;}.errorBreak{cursor:pointer;display:none;margin:0 6px 0 0;width:13px;height:14px;vertical-align:bottom;opacity:0.1;}.hasBreakSwitch .errorBreak{display:inline;}.breakForError .errorBreak{opacity:1;}.assertDescription{margin:0;}.logRow-profile > .logRow > .objectBox-text{font-family:Lucida Grande,Tahoma,sans-serif;color:#000000;}.logRow-profile > .logRow > .objectBox-text:last-child{color:#555555;font-style:italic;}.logRow-profile.opened > .logRow{padding-bottom:4px;}.profilerRunning > .logRow{padding-left:22px !important;}.profileSizer{width:100%;overflow-x:auto;overflow-y:scroll;}.profileTable{border-bottom:1px solid #D7D7D7;padding:0 0 4px 0;}.profileTable tr[odd="1"]{background-color:#F5F5F5;vertical-align:middle;}.profileTable a{vertical-align:middle;}.profileTable td{padding:1px 4px 0 4px;}.headerCell{cursor:pointer;-moz-user-select:none;border-bottom:1px solid #9C9C9C;padding:0 !important;font-weight:bold;}.headerCellBox{padding:2px 4px;border-left:1px solid #D9D9D9;border-right:1px solid #9C9C9C;}.headerCell:hover:active{}.headerSorted{}.headerSorted > .headerCellBox{border-right-color:#6B7C93;}.headerSorted.sortedAscending > .headerCellBox{}.headerSorted:hover:active{}.linkCell{text-align:right;}.linkCell > .objectLink-sourceLink{position:static;}.logRow-stackTrace{padding-top:0;background:#f8f8f8;}.logRow-stackTrace > .objectBox-stackFrame{position:relative;padding-top:2px;}.objectLink-object{font-family:Lucida Grande,sans-serif;font-weight:bold;color:DarkGreen;white-space:pre-wrap;}.objectProp-object{color:DarkGreen;}.objectProps{color:#000;font-weight:normal;}.objectPropName{color:#777;}.objectProps .objectProp-string{color:#f55;}.objectProps .objectProp-number{color:#55a;}.objectProps .objectProp-object{color:#585;}.selectorTag,.selectorId,.selectorClass{font-family:Monaco,monospace;font-weight:normal;}.selectorTag{color:#0000FF;}.selectorId{color:DarkBlue;}.selectorClass{color:red;}.selectorHidden > .selectorTag{color:#5F82D9;}.selectorHidden > .selectorId{color:#888888;}.selectorHidden > .selectorClass{color:#D86060;}.selectorValue{font-family:Lucida Grande,sans-serif;font-style:italic;color:#555555;}.panelNode.searching .logRow{display:none;}.logRow.matched{display:block !important;}.logRow.matching{position:absolute;left:-1000px;top:-1000px;max-width:0;max-height:0;overflow:hidden;}.objectLeftBrace,.objectRightBrace,.objectEqual,.objectComma,.arrayLeftBracket,.arrayRightBracket,.arrayComma{font-family:Monaco,monospace;}.objectLeftBrace,.objectRightBrace,.arrayLeftBracket,.arrayRightBracket{font-weight:bold;}.objectLeftBrace,.arrayLeftBracket{margin-right:4px;}.objectRightBrace,.arrayRightBracket{margin-left:4px;}.logRow-dir{padding:0;}.logRow-errorMessage .hasTwisty .errorTitle,.logRow-spy .spyHead .spyTitle,.logGroup .logRow{cursor:pointer;padding-left:18px;background-repeat:no-repeat;background-position:3px 3px;}.logRow-errorMessage > .hasTwisty > .errorTitle{background-position:2px 3px;}.logRow-errorMessage > .hasTwisty > .errorTitle:hover,.logRow-spy .spyHead .spyTitle:hover,.logGroup > .logRow:hover{text-decoration:underline;}.logRow-spy{padding:0 !important;}.logRow-spy,.logRow-spy .objectLink-sourceLink{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/group.gif) repeat-x #FFFFFF;padding-right:4px;right:0;}.logRow-spy.opened{padding-bottom:4px;border-bottom:none;}.spyTitle{color:#000000;font-weight:bold;-moz-box-sizing:padding-box;overflow:hidden;z-index:100;padding-left:18px;}.spyCol{padding:0;white-space:nowrap;height:16px;}.spyTitleCol:hover > .objectLink-sourceLink,.spyTitleCol:hover > .spyTime,.spyTitleCol:hover > .spyStatus,.spyTitleCol:hover > .spyTitle{display:none;}.spyFullTitle{display:none;-moz-user-select:none;max-width:100%;background-color:Transparent;}.spyTitleCol:hover > .spyFullTitle{display:block;}.spyStatus{padding-left:10px;color:rgb(128,128,128);}.spyTime{margin-left:4px;margin-right:4px;color:rgb(128,128,128);}.spyIcon{margin-right:4px;margin-left:4px;width:16px;height:16px;vertical-align:middle;background:transparent no-repeat 0 0;display:none;}.loading .spyHead .spyRow .spyIcon{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/loading_16.gif);display:block;}.logRow-spy.loaded:not(.error) .spyHead .spyRow .spyIcon{width:0;margin:0;}.logRow-spy.error .spyHead .spyRow .spyIcon{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon-sm.png);display:block;background-position:2px 2px;}.logRow-spy .spyHead .netInfoBody{display:none;}.logRow-spy.opened .spyHead .netInfoBody{margin-top:10px;display:block;}.logRow-spy.error .spyTitle,.logRow-spy.error .spyStatus,.logRow-spy.error .spyTime{color:red;}.logRow-spy.loading .spyResponseText{font-style:italic;color:#888888;}.caption{font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#444444;}.warning{padding:10px;font-family:Lucida Grande,Tahoma,sans-serif;font-weight:bold;color:#888888;}.panelNode-dom{overflow-x:hidden !important;}.domTable{font-size:1em;width:100%;table-layout:fixed;background:#fff;}.domTableIE{width:auto;}.memberLabelCell{padding:2px 0 2px 0;vertical-align:top;}.memberValueCell{padding:1px 0 1px 5px;display:block;overflow:hidden;}.memberLabel{display:block;cursor:default;-moz-user-select:none;overflow:hidden;padding-left:18px;background-color:#FFFFFF;text-decoration:none;}.memberRow.hasChildren .memberLabelCell .memberLabel:hover{cursor:pointer;color:blue;text-decoration:underline;}.userLabel{color:#000000;font-weight:bold;}.userClassLabel{color:#E90000;font-weight:bold;}.userFunctionLabel{color:#025E2A;font-weight:bold;}.domLabel{color:#000000;}.domFunctionLabel{color:#025E2A;}.ordinalLabel{color:SlateBlue;font-weight:bold;}.scopesRow{padding:2px 18px;background-color:LightYellow;border-bottom:5px solid #BEBEBE;color:#666666;}.scopesLabel{background-color:LightYellow;}.watchEditCell{padding:2px 18px;background-color:LightYellow;border-bottom:1px solid #BEBEBE;color:#666666;}.editor-watchNewRow,.editor-memberRow{font-family:Monaco,monospace !important;}.editor-memberRow{padding:1px 0 !important;}.editor-watchRow{padding-bottom:0 !important;}.watchRow > .memberLabelCell{font-family:Monaco,monospace;padding-top:1px;padding-bottom:1px;}.watchRow > .memberLabelCell > .memberLabel{background-color:transparent;}.watchRow > .memberValueCell{padding-top:2px;padding-bottom:2px;}.watchRow > .memberLabelCell,.watchRow > .memberValueCell{background-color:#F5F5F5;border-bottom:1px solid #BEBEBE;}.watchToolbox{z-index:2147483647;position:absolute;right:0;padding:1px 2px;}#fbConsole{overflow-x:hidden !important;}#fbCSS{font:1em Monaco,monospace;padding:0 7px;}#fbstylesheetButtons select,#fbScriptButtons select{font:11px Lucida Grande,Tahoma,sans-serif;margin-top:1px;padding-left:3px;background:#fafafa;border:1px inset #fff;width:220px;outline:none;}.Selector{margin-top:10px}.CSSItem{margin-left:4%}.CSSText{padding-left:20px;}.CSSProperty{color:#005500;}.CSSValue{padding-left:5px; color:#000088;}#fbHTMLStatusBar{display:inline;}.fbToolbarButtons{display:none;}.fbStatusSeparator{display:block;float:left;padding-top:4px;}#fbStatusBarBox{display:none;}#fbToolbarContent{display:block;position:absolute;_position:absolute;top:0;padding-top:4px;height:23px;clip:rect(0,2048px,27px,0);}.fbTabMenuTarget{display:none !important;float:left;width:10px;height:10px;margin-top:6px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuTarget.png);}.fbTabMenuTarget:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuTargetHover.png);}.fbShadow{float:left;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/shadowAlpha.png) no-repeat bottom right !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/shadow2.gif) no-repeat bottom right;margin:10px 0 0 10px !important;margin:10px 0 0 5px;}.fbShadowContent{display:block;position:relative;background-color:#fff;border:1px solid #a9a9a9;top:-6px;left:-6px;}.fbMenu{display:none;position:absolute;font-size:11px;line-height:13px;z-index:2147483647;}.fbMenuContent{padding:2px;}.fbMenuSeparator{display:block;position:relative;padding:1px 18px 0;text-decoration:none;color:#000;cursor:default;background:#ACA899;margin:4px 0;}.fbMenuOption{display:block;position:relative;padding:2px 18px;text-decoration:none;color:#000;cursor:default;}.fbMenuOption:hover{color:#fff;background:#316AC5;}.fbMenuGroup{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right 0;}.fbMenuGroup:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuGroupSelected{color:#fff;background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuPin.png) no-repeat right -17px;}.fbMenuChecked{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuCheckbox.png) no-repeat 4px 0;}.fbMenuChecked:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuCheckbox.png) no-repeat 4px -17px;}.fbMenuRadioSelected{background:transparent url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuRadio.png) no-repeat 4px 0;}.fbMenuRadioSelected:hover{background:#316AC5 url(https://getfirebug.com/releases/lite/latest/skin/xp/tabMenuRadio.png) no-repeat 4px -17px;}.fbMenuShortcut{padding-right:85px;}.fbMenuShortcutKey{position:absolute;right:0;top:2px;width:77px;}#fbFirebugMenu{top:22px;left:0;}.fbMenuDisabled{color:#ACA899 !important;}#fbFirebugSettingsMenu{left:245px;top:99px;}#fbConsoleMenu{top:42px;left:48px;}.fbIconButton{display:block;}.fbIconButton{display:block;}.fbIconButton{display:block;float:left;height:20px;width:20px;color:#000;margin-right:2px;text-decoration:none;cursor:default;}.fbIconButton:hover{position:relative;top:-1px;left:-1px;margin-right:0;_margin-right:1px;color:#333;border:1px solid #fff;border-bottom:1px solid #bbb;border-right:1px solid #bbb;}.fbIconPressed{position:relative;margin-right:0;_margin-right:1px;top:0 !important;left:0 !important;height:19px;color:#333 !important;border:1px solid #bbb !important;border-bottom:1px solid #cfcfcf !important;border-right:1px solid #ddd !important;}#fbErrorPopup{position:absolute;right:0;bottom:0;height:19px;width:75px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;z-index:999;}#fbErrorPopupContent{position:absolute;right:0;top:1px;height:18px;width:75px;_width:74px;border-left:1px solid #aca899;}#fbErrorIndicator{position:absolute;top:2px;right:5px;}.fbBtnInspectActive{background:#aaa;color:#fff !important;}.fbBody{margin:0;padding:0;overflow:hidden;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;background:#fff;}.clear{clear:both;}#fbMiniChrome{display:none;right:0;height:27px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;margin-left:1px;}#fbMiniContent{display:block;position:relative;left:-1px;right:0;top:1px;height:25px;border-left:1px solid #aca899;}#fbToolbarSearch{float:right;border:1px solid #ccc;margin:0 5px 0 0;background:#fff url(https://getfirebug.com/releases/lite/latest/skin/xp/search.png) no-repeat 4px 2px !important;background:#fff url(https://getfirebug.com/releases/lite/latest/skin/xp/search.gif) no-repeat 4px 2px;padding-left:20px;font-size:11px;}#fbToolbarErrors{float:right;margin:1px 4px 0 0;font-size:11px;}#fbLeftToolbarErrors{float:left;margin:7px 0px 0 5px;font-size:11px;}.fbErrors{padding-left:20px;height:14px;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.png) no-repeat !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.gif) no-repeat;color:#f00;font-weight:bold;}#fbMiniErrors{display:inline;display:none;float:right;margin:5px 2px 0 5px;}#fbMiniIcon{float:right;margin:3px 4px 0;height:20px;width:20px;float:right;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -135px;cursor:pointer;}#fbChrome{font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;position:absolute;_position:static;top:0;left:0;height:100%;width:100%;border-collapse:collapse;border-spacing:0;background:#fff;overflow:hidden;}#fbChrome > tbody > tr > td{padding:0;}#fbTop{height:49px;}#fbToolbar{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;height:27px;font-size:11px;line-height:13px;}#fbPanelBarBox{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;height:22px;}#fbContent{height:100%;vertical-align:top;}#fbBottom{height:18px;background:#fff;}#fbToolbarIcon{float:left;padding:0 5px 0;}#fbToolbarIcon a{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -135px;}#fbToolbarButtons{padding:0 2px 0 5px;}#fbToolbarButtons{padding:0 2px 0 5px;}.fbButton{text-decoration:none;display:block;float:left;color:#000;padding:4px 6px 4px 7px;cursor:default;}.fbButton:hover{color:#333;background:#f5f5ef url(https://getfirebug.com/releases/lite/latest/skin/xp/buttonBg.png);padding:3px 5px 3px 6px;border:1px solid #fff;border-bottom:1px solid #bbb;border-right:1px solid #bbb;}.fbBtnPressed{background:#e3e3db url(https://getfirebug.com/releases/lite/latest/skin/xp/buttonBgHover.png) !important;padding:3px 4px 2px 6px !important;margin:1px 0 0 1px !important;border:1px solid #ACA899 !important;border-color:#ACA899 #ECEBE3 #ECEBE3 #ACA899 !important;}#fbStatusBarBox{top:4px;cursor:default;}.fbToolbarSeparator{overflow:hidden;border:1px solid;border-color:transparent #fff transparent #777;_border-color:#eee #fff #eee #777;height:7px;margin:6px 3px;float:left;}.fbBtnSelected{font-weight:bold;}.fbStatusBar{color:#aca899;}.fbStatusBar a{text-decoration:none;color:black;}.fbStatusBar a:hover{color:blue;cursor:pointer;}#fbWindowButtons{position:absolute;white-space:nowrap;right:0;top:0;height:17px;width:48px;padding:5px;z-index:6;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 0;}#fbPanelBar1{width:1024px; z-index:8;left:0;white-space:nowrap;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;left:4px;}#fbPanelBar2Box{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #dbd9c9 0 -27px;position:absolute;height:22px;width:300px; z-index:9;right:0;}#fbPanelBar2{position:absolute;width:290px; height:22px;padding-left:4px;}.fbPanel{display:none;}#fbPanelBox1,#fbPanelBox2{max-height:inherit;height:100%;font-size:1em;}#fbPanelBox2{background:#fff;}#fbPanelBox2{width:300px;background:#fff;}#fbPanel2{margin-left:6px;background:#fff;}#fbLargeCommandLine{display:none;position:absolute;z-index:9;top:27px;right:0;width:294px;height:201px;border-width:0;margin:0;padding:2px 0 0 2px;resize:none;outline:none;font-size:11px;overflow:auto;border-top:1px solid #B9B7AF;_right:-1px;_border-left:1px solid #fff;}#fbLargeCommandButtons{display:none;background:#ECE9D8;bottom:0;right:0;width:294px;height:21px;padding-top:1px;position:fixed;border-top:1px solid #ACA899;z-index:9;}#fbSmallCommandLineIcon{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/down.png) no-repeat;position:absolute;right:2px;bottom:3px;z-index:99;}#fbSmallCommandLineIcon:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/downHover.png) no-repeat;}.hide{overflow:hidden !important;position:fixed !important;display:none !important;visibility:hidden !important;}#fbCommand{height:18px;}#fbCommandBox{position:fixed;_position:absolute;width:100%;height:18px;bottom:0;overflow:hidden;z-index:9;background:#fff;border:0;border-top:1px solid #ccc;}#fbCommandIcon{position:absolute;color:#00f;top:2px;left:6px;display:inline;font:11px Monaco,monospace;z-index:10;}#fbCommandLine{position:absolute;width:100%;top:0;left:0;border:0;margin:0;padding:2px 0 2px 32px;font:11px Monaco,monospace;z-index:9;outline:none;}#fbLargeCommandLineIcon{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/up.png) no-repeat;position:absolute;right:1px;bottom:1px;z-index:10;}#fbLargeCommandLineIcon:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/upHover.png) no-repeat;}div.fbFitHeight{overflow:auto;position:relative;}.fbSmallButton{overflow:hidden;width:16px;height:16px;display:block;text-decoration:none;cursor:default;}#fbWindowButtons .fbSmallButton{float:right;}#fbWindow_btClose{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/min.png);}#fbWindow_btClose:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/minHover.png);}#fbWindow_btDetach{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/detach.png);}#fbWindow_btDetach:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/detachHover.png);}#fbWindow_btDeactivate{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/off.png);}#fbWindow_btDeactivate:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/offHover.png);}.fbTab{text-decoration:none;display:none;float:left;width:auto;float:left;cursor:default;font-family:Lucida Grande,Tahoma,sans-serif;font-size:11px;line-height:13px;font-weight:bold;height:22px;color:#565656;}.fbPanelBar span{float:left;}.fbPanelBar .fbTabL,.fbPanelBar .fbTabR{height:22px;width:8px;}.fbPanelBar .fbTabText{padding:4px 1px 0;}a.fbTab:hover{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -73px;}a.fbTab:hover .fbTabL{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -16px -96px;}a.fbTab:hover .fbTabR{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -24px -96px;}.fbSelectedTab{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) #f1f2ee 0 -50px !important;color:#000;}.fbSelectedTab .fbTabL{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) 0 -96px !important;}.fbSelectedTab .fbTabR{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/sprite.png) -8px -96px !important;}#fbHSplitter{position:fixed;_position:absolute;left:0;top:0;width:100%;height:5px;overflow:hidden;cursor:n-resize !important;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/pixel_transparent.gif);z-index:9;}#fbHSplitter.fbOnMovingHSplitter{height:100%;z-index:100;}.fbVSplitter{background:#ece9d8;color:#000;border:1px solid #716f64;border-width:0 1px;border-left-color:#aca899;width:4px;cursor:e-resize;overflow:hidden;right:294px;text-decoration:none;z-index:10;position:absolute;height:100%;top:27px;}div.lineNo{font:1em/1.4545em Monaco,monospace;position:relative;float:left;top:0;left:0;margin:0 5px 0 0;padding:0 5px 0 10px;background:#eee;color:#888;border-right:1px solid #ccc;text-align:right;}.sourceBox{position:absolute;}.sourceCode{font:1em Monaco,monospace;overflow:hidden;white-space:pre;display:inline;}.nodeControl{margin-top:3px;margin-left:-14px;float:left;width:9px;height:9px;overflow:hidden;cursor:default;background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_open.gif);_float:none;_display:inline;_position:absolute;}div.nodeMaximized{background:url(https://getfirebug.com/releases/lite/latest/skin/xp/tree_close.gif);}div.objectBox-element{padding:1px 3px;}.objectBox-selector{cursor:default;}.selectedElement{background:highlight;color:#fff !important;}.selectedElement span{color:#fff !important;}* html .selectedElement{position:relative;}@media screen and (-webkit-min-device-pixel-ratio:0){.selectedElement{background:#316AC5;color:#fff !important;}}.logRow *{font-size:1em;}.logRow{position:relative;border-bottom:1px solid #D7D7D7;padding:2px 4px 1px 6px;zbackground-color:#FFFFFF;}.logRow-command{font-family:Monaco,monospace;color:blue;}.objectBox-string,.objectBox-text,.objectBox-number,.objectBox-function,.objectLink-element,.objectLink-textNode,.objectLink-function,.objectBox-stackTrace,.objectLink-profile{font-family:Monaco,monospace;}.objectBox-null{padding:0 2px;border:1px solid #666666;background-color:#888888;color:#FFFFFF;}.objectBox-string{color:red;}.objectBox-number{color:#000088;}.objectBox-function{color:DarkGreen;}.objectBox-object{color:DarkGreen;font-weight:bold;font-family:Lucida Grande,sans-serif;}.objectBox-array{color:#000;}.logRow-info,.logRow-error,.logRow-warn{background:#fff no-repeat 2px 2px;padding-left:20px;padding-bottom:3px;}.logRow-info{background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/infoIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/infoIcon.gif);}.logRow-warn{background-color:cyan;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/warningIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/warningIcon.gif);}.logRow-error{background-color:LightYellow;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.png) !important;background-image:url(https://getfirebug.com/releases/lite/latest/skin/xp/errorIcon.gif);color:#f00;}.errorMessage{vertical-align:top;color:#f00;}.objectBox-sourceLink{position:absolute;right:4px;top:2px;padding-left:8px;font-family:Lucida Grande,sans-serif;font-weight:bold;color:#0000FF;}.selectorTag,.selectorId,.selectorClass{font-family:Monaco,monospace;font-weight:normal;}.selectorTag{color:#0000FF;}.selectorId{color:DarkBlue;}.selectorClass{color:red;}.objectBox-element{font-family:Monaco,monospace;color:#000088;}.nodeChildren{padding-left:26px;}.nodeTag{color:blue;cursor:pointer;}.nodeValue{color:#FF0000;font-weight:normal;}.nodeText,.nodeComment{margin:0 2px;vertical-align:top;}.nodeText{color:#333333;font-family:Monaco,monospace;}.nodeComment{color:DarkGreen;}.nodeHidden,.nodeHidden *{color:#888888;}.nodeHidden .nodeTag{color:#5F82D9;}.nodeHidden .nodeValue{color:#D86060;}.selectedElement .nodeHidden,.selectedElement .nodeHidden *{color:SkyBlue !important;}.log-object{}.property{position:relative;clear:both;height:15px;}.propertyNameCell{vertical-align:top;float:left;width:28%;position:absolute;left:0;z-index:0;}.propertyValueCell{float:right;width:68%;background:#fff;position:absolute;padding-left:5px;display:table-cell;right:0;z-index:1;}.propertyName{font-weight:bold;}.FirebugPopup{height:100% !important;}.FirebugPopup #fbWindowButtons{display:none !important;}.FirebugPopup #fbHSplitter{display:none !important;}',
+    HTML: '<table id="fbChrome" cellpadding="0" cellspacing="0" border="0"><tbody><tr><td id="fbTop" colspan="2"><div id="fbWindowButtons"><a id="fbWindow_btDeactivate" class="fbSmallButton fbHover" title="Deactivate Firebug for this web page">&nbsp;</a><a id="fbWindow_btDetach" class="fbSmallButton fbHover" title="Open Firebug in popup window">&nbsp;</a><a id="fbWindow_btClose" class="fbSmallButton fbHover" title="Minimize Firebug">&nbsp;</a></div><div id="fbToolbar"><div id="fbToolbarContent"><span id="fbToolbarIcon"><a id="fbFirebugButton" class="fbIconButton" class="fbHover" target="_blank">&nbsp;</a></span><span id="fbToolbarButtons"><span id="fbFixedButtons"><a id="fbChrome_btInspect" class="fbButton fbHover" title="Click an element in the page to inspect">Inspect</a></span><span id="fbConsoleButtons" class="fbToolbarButtons"><a id="fbConsole_btClear" class="fbButton fbHover" title="Clear the console">Clear</a></span></span><span id="fbStatusBarBox"><span class="fbToolbarSeparator"></span></span></div></div><div id="fbPanelBarBox"><div id="fbPanelBar1" class="fbPanelBar"><a id="fbConsoleTab" class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">Console</span><span class="fbTabMenuTarget"></span><span class="fbTabR"></span></a><a id="fbHTMLTab" class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">HTML</span><span class="fbTabR"></span></a><a class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">CSS</span><span class="fbTabR"></span></a><a class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">Script</span><span class="fbTabR"></span></a><a class="fbTab fbHover"><span class="fbTabL"></span><span class="fbTabText">DOM</span><span class="fbTabR"></span></a></div><div id="fbPanelBar2Box" class="hide"><div id="fbPanelBar2" class="fbPanelBar"></div></div></div><div id="fbHSplitter">&nbsp;</div></td></tr><tr id="fbContent"><td id="fbPanelBox1"><div id="fbPanel1" class="fbFitHeight"><div id="fbConsole" class="fbPanel"></div><div id="fbHTML" class="fbPanel"></div></div></td><td id="fbPanelBox2" class="hide"><div id="fbVSplitter" class="fbVSplitter">&nbsp;</div><div id="fbPanel2" class="fbFitHeight"><div id="fbHTML_Style" class="fbPanel"></div><div id="fbHTML_Layout" class="fbPanel"></div><div id="fbHTML_DOM" class="fbPanel"></div></div><textarea id="fbLargeCommandLine" class="fbFitHeight"></textarea><div id="fbLargeCommandButtons"><a id="fbCommand_btRun" class="fbButton fbHover">Run</a><a id="fbCommand_btClear" class="fbButton fbHover">Clear</a><a id="fbSmallCommandLineIcon" class="fbSmallButton fbHover"></a></div></td></tr><tr id="fbBottom" class="hide"><td id="fbCommand" colspan="2"><div id="fbCommandBox"><div id="fbCommandIcon">&gt;&gt;&gt;</div><input id="fbCommandLine" name="fbCommandLine" type="text"/><a id="fbLargeCommandLineIcon" class="fbSmallButton fbHover"></a></div></td></tr></tbody></table><span id="fbMiniChrome"><span id="fbMiniContent"><span id="fbMiniIcon" title="Open Firebug Lite"></span><span id="fbMiniErrors" class="fbErrors"></span></span></span>'
+};
+
+// ************************************************************************************************
+}});
+
+// ************************************************************************************************
+FBL.initialize();
+// ************************************************************************************************
+
+})();
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/json-js/json2.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/json-js/json2.js
new file mode 100644
index 0000000..5838457
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/json-js/json2.js
@@ -0,0 +1,519 @@
+/*
+    json2.js
+    2015-05-03
+
+    Public Domain.
+
+    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+    See http://www.JSON.org/js.html
+
+
+    This code should be minified before deployment.
+    See http://javascript.crockford.com/jsmin.html
+
+    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+    NOT CONTROL.
+
+
+    This file creates a global JSON object containing two methods: stringify
+    and parse. This file is provides the ES5 JSON capability to ES3 systems.
+    If a project might run on IE8 or earlier, then this file should be included.
+    This file does nothing on ES5 systems.
+
+        JSON.stringify(value, replacer, space)
+            value       any JavaScript value, usually an object or array.
+
+            replacer    an optional parameter that determines how object
+                        values are stringified for objects. It can be a
+                        function or an array of strings.
+
+            space       an optional parameter that specifies the indentation
+                        of nested structures. If it is omitted, the text will
+                        be packed without extra whitespace. If it is a number,
+                        it will specify the number of spaces to indent at each
+                        level. If it is a string (such as '\t' or '&nbsp;'),
+                        it contains the characters used to indent at each level.
+
+            This method produces a JSON text from a JavaScript value.
+
+            When an object value is found, if the object contains a toJSON
+            method, its toJSON method will be called and the result will be
+            stringified. A toJSON method does not serialize: it returns the
+            value represented by the name/value pair that should be serialized,
+            or undefined if nothing should be serialized. The toJSON method
+            will be passed the key associated with the value, and this will be
+            bound to the value
+
+            For example, this would serialize Dates as ISO strings.
+
+                Date.prototype.toJSON = function (key) {
+                    function f(n) {
+                        // Format integers to have at least two digits.
+                        return n < 10 
+                            ? '0' + n 
+                            : n;
+                    }
+
+                    return this.getUTCFullYear()   + '-' +
+                         f(this.getUTCMonth() + 1) + '-' +
+                         f(this.getUTCDate())      + 'T' +
+                         f(this.getUTCHours())     + ':' +
+                         f(this.getUTCMinutes())   + ':' +
+                         f(this.getUTCSeconds())   + 'Z';
+                };
+
+            You can provide an optional replacer method. It will be passed the
+            key and value of each member, with this bound to the containing
+            object. The value that is returned from your method will be
+            serialized. If your method returns undefined, then the member will
+            be excluded from the serialization.
+
+            If the replacer parameter is an array of strings, then it will be
+            used to select the members to be serialized. It filters the results
+            such that only members with keys listed in the replacer array are
+            stringified.
+
+            Values that do not have JSON representations, such as undefined or
+            functions, will not be serialized. Such values in objects will be
+            dropped; in arrays they will be replaced with null. You can use
+            a replacer function to replace those with JSON values.
+            JSON.stringify(undefined) returns undefined.
+
+            The optional space parameter produces a stringification of the
+            value that is filled with line breaks and indentation to make it
+            easier to read.
+
+            If the space parameter is a non-empty string, then that string will
+            be used for indentation. If the space parameter is a number, then
+            the indentation will be that many spaces.
+
+            Example:
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}]);
+            // text is '["e",{"pluribus":"unum"}]'
+
+
+            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+            text = JSON.stringify([new Date()], function (key, value) {
+                return this[key] instanceof Date 
+                    ? 'Date(' + this[key] + ')' 
+                    : value;
+            });
+            // text is '["Date(---current time---)"]'
+
+
+        JSON.parse(text, reviver)
+            This method parses a JSON text to produce an object or array.
+            It can throw a SyntaxError exception.
+
+            The optional reviver parameter is a function that can filter and
+            transform the results. It receives each of the keys and values,
+            and its return value is used instead of the original value.
+            If it returns what it received, then the structure is not modified.
+            If it returns undefined then the member is deleted.
+
+            Example:
+
+            // Parse the text. Values that look like ISO date strings will
+            // be converted to Date objects.
+
+            myData = JSON.parse(text, function (key, value) {
+                var a;
+                if (typeof value === 'string') {
+                    a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+                    if (a) {
+                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+                            +a[5], +a[6]));
+                    }
+                }
+                return value;
+            });
+
+            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+                var d;
+                if (typeof value === 'string' &&
+                        value.slice(0, 5) === 'Date(' &&
+                        value.slice(-1) === ')') {
+                    d = new Date(value.slice(5, -1));
+                    if (d) {
+                        return d;
+                    }
+                }
+                return value;
+            });
+
+
+    This is a reference implementation. You are free to copy, modify, or
+    redistribute.
+*/
+
+/*jslint 
+    eval, for, this 
+*/
+
+/*property
+    JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (typeof JSON !== 'object') {
+    JSON = {};
+}
+
+(function () {
+    'use strict';
+    
+    var rx_one = /^[\],:{}\s]*$/,
+        rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+        rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+        rx_four = /(?:^|:|,)(?:\s*\[)+/g,
+        rx_escapable = /[\\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+        rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10 
+            ? '0' + n 
+            : n;
+    }
+    
+    function this_value() {
+        return this.valueOf();
+    }
+
+    if (typeof Date.prototype.toJSON !== 'function') {
+
+        Date.prototype.toJSON = function () {
+
+            return isFinite(this.valueOf())
+                ? this.getUTCFullYear() + '-' +
+                        f(this.getUTCMonth() + 1) + '-' +
+                        f(this.getUTCDate()) + 'T' +
+                        f(this.getUTCHours()) + ':' +
+                        f(this.getUTCMinutes()) + ':' +
+                        f(this.getUTCSeconds()) + 'Z'
+                : null;
+        };
+
+        Boolean.prototype.toJSON = this_value;
+        Number.prototype.toJSON = this_value;
+        String.prototype.toJSON = this_value;
+    }
+
+    var gap,
+        indent,
+        meta,
+        rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        rx_escapable.lastIndex = 0;
+        return rx_escapable.test(string) 
+            ? '"' + string.replace(rx_escapable, function (a) {
+                var c = meta[a];
+                return typeof c === 'string'
+                    ? c
+                    : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + '"' 
+            : '"' + string + '"';
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i,          // The loop counter.
+            k,          // The member key.
+            v,          // The member value.
+            length,
+            mind = gap,
+            partial,
+            value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === 'object' &&
+                typeof value.toJSON === 'function') {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === 'function') {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case 'string':
+            return quote(value);
+
+        case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value) 
+                ? String(value) 
+                : 'null';
+
+        case 'boolean':
+        case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+        case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+            if (!value) {
+                return 'null';
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || 'null';
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0
+                    ? '[]'
+                    : gap
+                        ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
+                        : '[' + partial.join(',') + ']';
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === 'object') {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    if (typeof rep[i] === 'string') {
+                        k = rep[i];
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (
+                                gap 
+                                    ? ': ' 
+                                    : ':'
+                            ) + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (
+                                gap 
+                                    ? ': ' 
+                                    : ':'
+                            ) + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0
+                ? '{}'
+                : gap
+                    ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
+                    : '{' + partial.join(',') + '}';
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== 'function') {
+        meta = {    // table of character substitutions
+            '\b': '\\b',
+            '\t': '\\t',
+            '\n': '\\n',
+            '\f': '\\f',
+            '\r': '\\r',
+            '"': '\\"',
+            '\\': '\\\\'
+        };
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = '';
+            indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === 'number') {
+                for (i = 0; i < space; i += 1) {
+                    indent += ' ';
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === 'string') {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== 'function' &&
+                    (typeof replacer !== 'object' ||
+                    typeof replacer.length !== 'number')) {
+                throw new Error('JSON.stringify');
+            }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+            return str('', {'': value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== 'function') {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k, v, value = holder[key];
+                if (value && typeof value === 'object') {
+                    for (k in value) {
+                        if (Object.prototype.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            rx_dangerous.lastIndex = 0;
+            if (rx_dangerous.test(text)) {
+                text = text.replace(rx_dangerous, function (a) {
+                    return '\\u' +
+                            ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+            if (
+                rx_one.test(
+                    text
+                        .replace(rx_two, '@')
+                        .replace(rx_three, ']')
+                        .replace(rx_four, '')
+                )
+            ) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return typeof reviver === 'function'
+                    ? walk({'': j}, '')
+                    : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError('JSON.parse');
+        };
+    }
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/LICENSE b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/LICENSE
new file mode 100644
index 0000000..447239f
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative
+Reporters & Editors
+
+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.
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/arrays.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/arrays.js
new file mode 100644
index 0000000..748edea
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/arrays.js
@@ -0,0 +1,555 @@
+(function() {
+  var _ = typeof require == 'function' ? require('..') : window._;
+
+  QUnit.module('Arrays');
+
+  QUnit.test('first', function(assert) {
+    assert.equal(_.first([1, 2, 3]), 1, 'can pull out the first element of an array');
+    assert.equal(_([1, 2, 3]).first(), 1, 'can perform OO-style "first()"');
+    assert.deepEqual(_.first([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
+    assert.deepEqual(_.first([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
+    assert.deepEqual(_.first([1, 2, 3], 2), [1, 2], 'can fetch the first n elements');
+    assert.deepEqual(_.first([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
+    var result = (function(){ return _.first(arguments); }(4, 3, 2, 1));
+    assert.equal(result, 4, 'works on an arguments object');
+    result = _.map([[1, 2, 3], [1, 2, 3]], _.first);
+    assert.deepEqual(result, [1, 1], 'works well with _.map');
+    assert.equal(_.first(null), void 0, 'returns undefined when called on null');
+  });
+
+  QUnit.test('head', function(assert) {
+    assert.strictEqual(_.head, _.first, 'is an alias for first');
+  });
+
+  QUnit.test('take', function(assert) {
+    assert.strictEqual(_.take, _.first, 'is an alias for first');
+  });
+
+  QUnit.test('rest', function(assert) {
+    var numbers = [1, 2, 3, 4];
+    assert.deepEqual(_.rest(numbers), [2, 3, 4], 'fetches all but the first element');
+    assert.deepEqual(_.rest(numbers, 0), [1, 2, 3, 4], 'returns the whole array when index is 0');
+    assert.deepEqual(_.rest(numbers, 2), [3, 4], 'returns elements starting at the given index');
+    var result = (function(){ return _(arguments).rest(); }(1, 2, 3, 4));
+    assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
+    result = _.map([[1, 2, 3], [1, 2, 3]], _.rest);
+    assert.deepEqual(_.flatten(result), [2, 3, 2, 3], 'works well with _.map');
+  });
+
+  QUnit.test('tail', function(assert) {
+    assert.strictEqual(_.tail, _.rest, 'is an alias for rest');
+  });
+
+  QUnit.test('drop', function(assert) {
+    assert.strictEqual(_.drop, _.rest, 'is an alias for rest');
+  });
+
+  QUnit.test('initial', function(assert) {
+    assert.deepEqual(_.initial([1, 2, 3, 4, 5]), [1, 2, 3, 4], 'returns all but the last element');
+    assert.deepEqual(_.initial([1, 2, 3, 4], 2), [1, 2], 'returns all but the last n elements');
+    assert.deepEqual(_.initial([1, 2, 3, 4], 6), [], 'returns an empty array when n > length');
+    var result = (function(){ return _(arguments).initial(); }(1, 2, 3, 4));
+    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
+    result = _.map([[1, 2, 3], [1, 2, 3]], _.initial);
+    assert.deepEqual(_.flatten(result), [1, 2, 1, 2], 'works well with _.map');
+  });
+
+  QUnit.test('last', function(assert) {
+    assert.equal(_.last([1, 2, 3]), 3, 'can pull out the last element of an array');
+    assert.equal(_([1, 2, 3]).last(), 3, 'can perform OO-style "last()"');
+    assert.deepEqual(_.last([1, 2, 3], 0), [], 'returns an empty array when n <= 0 (0 case)');
+    assert.deepEqual(_.last([1, 2, 3], -1), [], 'returns an empty array when n <= 0 (negative case)');
+    assert.deepEqual(_.last([1, 2, 3], 2), [2, 3], 'can fetch the last n elements');
+    assert.deepEqual(_.last([1, 2, 3], 5), [1, 2, 3], 'returns the whole array if n > length');
+    var result = (function(){ return _(arguments).last(); }(1, 2, 3, 4));
+    assert.equal(result, 4, 'works on an arguments object');
+    result = _.map([[1, 2, 3], [1, 2, 3]], _.last);
+    assert.deepEqual(result, [3, 3], 'works well with _.map');
+    assert.equal(_.last(null), void 0, 'returns undefined when called on null');
+  });
+
+  QUnit.test('compact', function(assert) {
+    assert.deepEqual(_.compact([1, false, null, 0, '', void 0, NaN, 2]), [1, 2], 'removes all falsy values');
+    var result = (function(){ return _.compact(arguments); }(0, 1, false, 2, false, 3));
+    assert.deepEqual(result, [1, 2, 3], 'works on an arguments object');
+    result = _.map([[1, false, false], [false, false, 3]], _.compact);
+    assert.deepEqual(result, [[1], [3]], 'works well with _.map');
+  });
+
+  QUnit.test('flatten', function(assert) {
+    assert.deepEqual(_.flatten(null), [], 'supports null');
+    assert.deepEqual(_.flatten(void 0), [], 'supports undefined');
+
+    assert.deepEqual(_.flatten([[], [[]], []]), [], 'supports empty arrays');
+    assert.deepEqual(_.flatten([[], [[]], []], true), [[]], 'can shallowly flatten empty arrays');
+
+    var list = [1, [2], [3, [[[4]]]]];
+    assert.deepEqual(_.flatten(list), [1, 2, 3, 4], 'can flatten nested arrays');
+    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [[[4]]]], 'can shallowly flatten nested arrays');
+    var result = (function(){ return _.flatten(arguments); }(1, [2], [3, [[[4]]]]));
+    assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
+    list = [[1], [2], [3], [[4]]];
+    assert.deepEqual(_.flatten(list, true), [1, 2, 3, [4]], 'can shallowly flatten arrays containing only other arrays');
+
+    assert.equal(_.flatten([_.range(10), _.range(10), 5, 1, 3], true).length, 23, 'can flatten medium length arrays');
+    assert.equal(_.flatten([_.range(10), _.range(10), 5, 1, 3]).length, 23, 'can shallowly flatten medium length arrays');
+    assert.equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3]).length, 1056003, 'can handle massive arrays');
+    assert.equal(_.flatten([new Array(1000000), _.range(56000), 5, 1, 3], true).length, 1056003, 'can handle massive arrays in shallow mode');
+
+    var x = _.range(100000);
+    for (var i = 0; i < 1000; i++) x = [x];
+    assert.deepEqual(_.flatten(x), _.range(100000), 'can handle very deep arrays');
+    assert.deepEqual(_.flatten(x, true), x[0], 'can handle very deep arrays in shallow mode');
+  });
+
+  QUnit.test('without', function(assert) {
+    var list = [1, 2, 1, 0, 3, 1, 4];
+    assert.deepEqual(_.without(list, 0, 1), [2, 3, 4], 'removes all instances of the given values');
+    var result = (function(){ return _.without(arguments, 0, 1); }(1, 2, 1, 0, 3, 1, 4));
+    assert.deepEqual(result, [2, 3, 4], 'works on an arguments object');
+
+    list = [{one: 1}, {two: 2}];
+    assert.deepEqual(_.without(list, {one: 1}), list, 'compares objects by reference (value case)');
+    assert.deepEqual(_.without(list, list[0]), [{two: 2}], 'compares objects by reference (reference case)');
+  });
+
+  QUnit.test('sortedIndex', function(assert) {
+    var numbers = [10, 20, 30, 40, 50];
+    var indexFor35 = _.sortedIndex(numbers, 35);
+    assert.equal(indexFor35, 3, 'finds the index at which a value should be inserted to retain order');
+    var indexFor30 = _.sortedIndex(numbers, 30);
+    assert.equal(indexFor30, 2, 'finds the smallest index at which a value could be inserted to retain order');
+
+    var objects = [{x: 10}, {x: 20}, {x: 30}, {x: 40}];
+    var iterator = function(obj){ return obj.x; };
+    assert.strictEqual(_.sortedIndex(objects, {x: 25}, iterator), 2, 'uses the result of `iterator` for order comparisons');
+    assert.strictEqual(_.sortedIndex(objects, {x: 35}, 'x'), 3, 'when `iterator` is a string, uses that key for order comparisons');
+
+    var context = {1: 2, 2: 3, 3: 4};
+    iterator = function(obj){ return this[obj]; };
+    assert.strictEqual(_.sortedIndex([1, 3], 2, iterator, context), 1, 'can execute its iterator in the given context');
+
+    var values = [0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287,
+        1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647];
+    var largeArray = Array(Math.pow(2, 32) - 1);
+    var length = values.length;
+    // Sparsely populate `array`
+    while (length--) {
+      largeArray[values[length]] = values[length];
+    }
+    assert.equal(_.sortedIndex(largeArray, 2147483648), 2147483648, 'works with large indexes');
+  });
+
+  QUnit.test('uniq', function(assert) {
+    var list = [1, 2, 1, 3, 1, 4];
+    assert.deepEqual(_.uniq(list), [1, 2, 3, 4], 'can find the unique values of an unsorted array');
+    list = [1, 1, 1, 2, 2, 3];
+    assert.deepEqual(_.uniq(list, true), [1, 2, 3], 'can find the unique values of a sorted array faster');
+
+    list = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}, {name: 'Curly'}];
+    var expected = [{name: 'Moe'}, {name: 'Curly'}, {name: 'Larry'}];
+    var iterator = function(stooge) { return stooge.name; };
+    assert.deepEqual(_.uniq(list, false, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (unsorted case)');
+    assert.deepEqual(_.uniq(list, iterator), expected, '`sorted` argument defaults to false when omitted');
+    assert.deepEqual(_.uniq(list, 'name'), expected, 'when `iterator` is a string, uses that key for comparisons (unsorted case)');
+
+    list = [{score: 8}, {score: 10}, {score: 10}];
+    expected = [{score: 8}, {score: 10}];
+    iterator = function(item) { return item.score; };
+    assert.deepEqual(_.uniq(list, true, iterator), expected, 'uses the result of `iterator` for uniqueness comparisons (sorted case)');
+    assert.deepEqual(_.uniq(list, true, 'score'), expected, 'when `iterator` is a string, uses that key for comparisons (sorted case)');
+
+    assert.deepEqual(_.uniq([{0: 1}, {0: 1}, {0: 1}, {0: 2}], 0), [{0: 1}, {0: 2}], 'can use falsey pluck like iterator');
+
+    var result = (function(){ return _.uniq(arguments); }(1, 2, 1, 3, 1, 4));
+    assert.deepEqual(result, [1, 2, 3, 4], 'works on an arguments object');
+
+    var a = {}, b = {}, c = {};
+    assert.deepEqual(_.uniq([a, b, a, b, c]), [a, b, c], 'works on values that can be tested for equivalency but not ordered');
+
+    assert.deepEqual(_.uniq(null), [], 'returns an empty array when `array` is not iterable');
+
+    var context = {};
+    list = [3];
+    _.uniq(list, function(value, index, array) {
+      assert.strictEqual(this, context, 'executes its iterator in the given context');
+      assert.strictEqual(value, 3, 'passes its iterator the value');
+      assert.strictEqual(index, 0, 'passes its iterator the index');
+      assert.strictEqual(array, list, 'passes its iterator the entire array');
+    }, context);
+
+  });
+
+  QUnit.test('unique', function(assert) {
+    assert.strictEqual(_.unique, _.uniq, 'is an alias for uniq');
+  });
+
+  QUnit.test('intersection', function(assert) {
+    var stooges = ['moe', 'curly', 'larry'], leaders = ['moe', 'groucho'];
+    assert.deepEqual(_.intersection(stooges, leaders), ['moe'], 'can find the set intersection of two arrays');
+    assert.deepEqual(_(stooges).intersection(leaders), ['moe'], 'can perform an OO-style intersection');
+    var result = (function(){ return _.intersection(arguments, leaders); }('moe', 'curly', 'larry'));
+    assert.deepEqual(result, ['moe'], 'works on an arguments object');
+    var theSixStooges = ['moe', 'moe', 'curly', 'curly', 'larry', 'larry'];
+    assert.deepEqual(_.intersection(theSixStooges, leaders), ['moe'], 'returns a duplicate-free array');
+    result = _.intersection([2, 4, 3, 1], [1, 2, 3]);
+    assert.deepEqual(result, [2, 3, 1], 'preserves the order of the first array');
+    result = _.intersection(null, [1, 2, 3]);
+    assert.deepEqual(result, [], 'returns an empty array when passed null as the first argument');
+    result = _.intersection([1, 2, 3], null);
+    assert.deepEqual(result, [], 'returns an empty array when passed null as an argument beyond the first');
+  });
+
+  QUnit.test('union', function(assert) {
+    var result = _.union([1, 2, 3], [2, 30, 1], [1, 40]);
+    assert.deepEqual(result, [1, 2, 3, 30, 40], 'can find the union of a list of arrays');
+
+    result = _([1, 2, 3]).union([2, 30, 1], [1, 40]);
+    assert.deepEqual(result, [1, 2, 3, 30, 40], 'can perform an OO-style union');
+
+    result = _.union([1, 2, 3], [2, 30, 1], [1, 40, [1]]);
+    assert.deepEqual(result, [1, 2, 3, 30, 40, [1]], 'can find the union of a list of nested arrays');
+
+    result = _.union([10, 20], [1, 30, 10], [0, 40]);
+    assert.deepEqual(result, [10, 20, 1, 30, 0, 40], 'orders values by their first encounter');
+
+    result = (function(){ return _.union(arguments, [2, 30, 1], [1, 40]); }(1, 2, 3));
+    assert.deepEqual(result, [1, 2, 3, 30, 40], 'works on an arguments object');
+
+    assert.deepEqual(_.union([1, 2, 3], 4), [1, 2, 3], 'restricts the union to arrays only');
+  });
+
+  QUnit.test('difference', function(assert) {
+    var result = _.difference([1, 2, 3], [2, 30, 40]);
+    assert.deepEqual(result, [1, 3], 'can find the difference of two arrays');
+
+    result = _([1, 2, 3]).difference([2, 30, 40]);
+    assert.deepEqual(result, [1, 3], 'can perform an OO-style difference');
+
+    result = _.difference([1, 2, 3, 4], [2, 30, 40], [1, 11, 111]);
+    assert.deepEqual(result, [3, 4], 'can find the difference of three arrays');
+
+    result = _.difference([8, 9, 3, 1], [3, 8]);
+    assert.deepEqual(result, [9, 1], 'preserves the order of the first array');
+
+    result = (function(){ return _.difference(arguments, [2, 30, 40]); }(1, 2, 3));
+    assert.deepEqual(result, [1, 3], 'works on an arguments object');
+
+    result = _.difference([1, 2, 3], 1);
+    assert.deepEqual(result, [1, 2, 3], 'restrict the difference to arrays only');
+  });
+
+  QUnit.test('zip', function(assert) {
+    var names = ['moe', 'larry', 'curly'], ages = [30, 40, 50], leaders = [true];
+    assert.deepEqual(_.zip(names, ages, leaders), [
+      ['moe', 30, true],
+      ['larry', 40, void 0],
+      ['curly', 50, void 0]
+    ], 'zipped together arrays of different lengths');
+
+    var stooges = _.zip(['moe', 30, 'stooge 1'], ['larry', 40, 'stooge 2'], ['curly', 50, 'stooge 3']);
+    assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], ['stooge 1', 'stooge 2', 'stooge 3']], 'zipped pairs');
+
+    // In the case of different lengths of the tuples, undefined values
+    // should be used as placeholder
+    stooges = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
+    assert.deepEqual(stooges, [['moe', 'larry', 'curly'], [30, 40, 50], [void 0, void 0, 'extra data']], 'zipped pairs with empties');
+
+    var empty = _.zip([]);
+    assert.deepEqual(empty, [], 'unzipped empty');
+
+    assert.deepEqual(_.zip(null), [], 'handles null');
+    assert.deepEqual(_.zip(), [], '_.zip() returns []');
+  });
+
+  QUnit.test('unzip', function(assert) {
+    assert.deepEqual(_.unzip(null), [], 'handles null');
+
+    assert.deepEqual(_.unzip([['a', 'b'], [1, 2]]), [['a', 1], ['b', 2]]);
+
+    // complements zip
+    var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]);
+    assert.deepEqual(_.unzip(zipped), [['fred', 'barney'], [30, 40], [true, false]]);
+
+    zipped = _.zip(['moe', 30], ['larry', 40], ['curly', 50, 'extra data']);
+    assert.deepEqual(_.unzip(zipped), [['moe', 30, void 0], ['larry', 40, void 0], ['curly', 50, 'extra data']], 'Uses length of largest array');
+  });
+
+  QUnit.test('object', function(assert) {
+    var result = _.object(['moe', 'larry', 'curly'], [30, 40, 50]);
+    var shouldBe = {moe: 30, larry: 40, curly: 50};
+    assert.deepEqual(result, shouldBe, 'two arrays zipped together into an object');
+
+    result = _.object([['one', 1], ['two', 2], ['three', 3]]);
+    shouldBe = {one: 1, two: 2, three: 3};
+    assert.deepEqual(result, shouldBe, 'an array of pairs zipped together into an object');
+
+    var stooges = {moe: 30, larry: 40, curly: 50};
+    assert.deepEqual(_.object(_.pairs(stooges)), stooges, 'an object converted to pairs and back to an object');
+
+    assert.deepEqual(_.object(null), {}, 'handles nulls');
+  });
+
+  QUnit.test('indexOf', function(assert) {
+    var numbers = [1, 2, 3];
+    assert.equal(_.indexOf(numbers, 2), 1, 'can compute indexOf');
+    var result = (function(){ return _.indexOf(arguments, 2); }(1, 2, 3));
+    assert.equal(result, 1, 'works on an arguments object');
+
+    _.each([null, void 0, [], false], function(val) {
+      var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
+      assert.equal(_.indexOf(val, 2), -1, msg);
+      assert.equal(_.indexOf(val, 2, -1), -1, msg);
+      assert.equal(_.indexOf(val, 2, -20), -1, msg);
+      assert.equal(_.indexOf(val, 2, 15), -1, msg);
+    });
+
+    var num = 35;
+    numbers = [10, 20, 30, 40, 50];
+    var index = _.indexOf(numbers, num, true);
+    assert.equal(index, -1, '35 is not in the list');
+
+    numbers = [10, 20, 30, 40, 50]; num = 40;
+    index = _.indexOf(numbers, num, true);
+    assert.equal(index, 3, '40 is in the list');
+
+    numbers = [1, 40, 40, 40, 40, 40, 40, 40, 50, 60, 70]; num = 40;
+    assert.equal(_.indexOf(numbers, num, true), 1, '40 is in the list');
+    assert.equal(_.indexOf(numbers, 6, true), -1, '6 isnt in the list');
+    assert.equal(_.indexOf([1, 2, 5, 4, 6, 7], 5, true), -1, 'sorted indexOf doesn\'t uses binary search');
+    assert.ok(_.every(['1', [], {}, null], function() {
+      return _.indexOf(numbers, num, {}) === 1;
+    }), 'non-nums as fromIndex make indexOf assume sorted');
+
+    numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
+    index = _.indexOf(numbers, 2, 5);
+    assert.equal(index, 7, 'supports the fromIndex argument');
+
+    index = _.indexOf([,,, 0], void 0);
+    assert.equal(index, 0, 'treats sparse arrays as if they were dense');
+
+    var array = [1, 2, 3, 1, 2, 3];
+    assert.strictEqual(_.indexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
+    assert.strictEqual(_.indexOf(array, 1, -2), -1, 'neg `fromIndex` starts at the right index');
+    assert.strictEqual(_.indexOf(array, 2, -3), 4);
+    _.each([-6, -8, -Infinity], function(fromIndex) {
+      assert.strictEqual(_.indexOf(array, 1, fromIndex), 0);
+    });
+    assert.strictEqual(_.indexOf([1, 2, 3], 1, true), 0);
+
+    index = _.indexOf([], void 0, true);
+    assert.equal(index, -1, 'empty array with truthy `isSorted` returns -1');
+  });
+
+  QUnit.test('indexOf with NaN', function(assert) {
+    assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN), 2, 'Expected [1, 2, NaN] to contain NaN');
+    assert.strictEqual(_.indexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
+
+    assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, 1), 2, 'startIndex does not affect result');
+    assert.strictEqual(_.indexOf([1, 2, NaN, NaN], NaN, -2), 2, 'startIndex does not affect result');
+
+    (function() {
+      assert.strictEqual(_.indexOf(arguments, NaN), 2, 'Expected arguments [1, 2, NaN] to contain NaN');
+    }(1, 2, NaN, NaN));
+  });
+
+  QUnit.test('indexOf with +- 0', function(assert) {
+    _.each([-0, +0], function(val) {
+      assert.strictEqual(_.indexOf([1, 2, val, val], val), 2);
+      assert.strictEqual(_.indexOf([1, 2, val, val], -val), 2);
+    });
+  });
+
+  QUnit.test('lastIndexOf', function(assert) {
+    var numbers = [1, 0, 1];
+    var falsey = [void 0, '', 0, false, NaN, null, void 0];
+    assert.equal(_.lastIndexOf(numbers, 1), 2);
+
+    numbers = [1, 0, 1, 0, 0, 1, 0, 0, 0];
+    numbers.lastIndexOf = null;
+    assert.equal(_.lastIndexOf(numbers, 1), 5, 'can compute lastIndexOf, even without the native function');
+    assert.equal(_.lastIndexOf(numbers, 0), 8, 'lastIndexOf the other element');
+    var result = (function(){ return _.lastIndexOf(arguments, 1); }(1, 0, 1, 0, 0, 1, 0, 0, 0));
+    assert.equal(result, 5, 'works on an arguments object');
+
+    _.each([null, void 0, [], false], function(val) {
+      var msg = 'Handles: ' + (_.isArray(val) ? '[]' : val);
+      assert.equal(_.lastIndexOf(val, 2), -1, msg);
+      assert.equal(_.lastIndexOf(val, 2, -1), -1, msg);
+      assert.equal(_.lastIndexOf(val, 2, -20), -1, msg);
+      assert.equal(_.lastIndexOf(val, 2, 15), -1, msg);
+    });
+
+    numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
+    var index = _.lastIndexOf(numbers, 2, 2);
+    assert.equal(index, 1, 'supports the fromIndex argument');
+
+    var array = [1, 2, 3, 1, 2, 3];
+
+    assert.strictEqual(_.lastIndexOf(array, 1, 0), 0, 'starts at the correct from idx');
+    assert.strictEqual(_.lastIndexOf(array, 3), 5, 'should return the index of the last matched value');
+    assert.strictEqual(_.lastIndexOf(array, 4), -1, 'should return `-1` for an unmatched value');
+
+    assert.strictEqual(_.lastIndexOf(array, 1, 2), 0, 'should work with a positive `fromIndex`');
+
+    _.each([6, 8, Math.pow(2, 32), Infinity], function(fromIndex) {
+      assert.strictEqual(_.lastIndexOf(array, void 0, fromIndex), -1);
+      assert.strictEqual(_.lastIndexOf(array, 1, fromIndex), 3);
+      assert.strictEqual(_.lastIndexOf(array, '', fromIndex), -1);
+    });
+
+    var expected = _.map(falsey, function(value) {
+      return typeof value == 'number' ? -1 : 5;
+    });
+
+    var actual = _.map(falsey, function(fromIndex) {
+      return _.lastIndexOf(array, 3, fromIndex);
+    });
+
+    assert.deepEqual(actual, expected, 'should treat falsey `fromIndex` values, except `0` and `NaN`, as `array.length`');
+    assert.strictEqual(_.lastIndexOf(array, 3, '1'), 5, 'should treat non-number `fromIndex` values as `array.length`');
+    assert.strictEqual(_.lastIndexOf(array, 3, true), 5, 'should treat non-number `fromIndex` values as `array.length`');
+
+    assert.strictEqual(_.lastIndexOf(array, 2, -3), 1, 'should work with a negative `fromIndex`');
+    assert.strictEqual(_.lastIndexOf(array, 1, -3), 3, 'neg `fromIndex` starts at the right index');
+
+    assert.deepEqual(_.map([-6, -8, -Infinity], function(fromIndex) {
+      return _.lastIndexOf(array, 1, fromIndex);
+    }), [0, -1, -1]);
+  });
+
+  QUnit.test('lastIndexOf with NaN', function(assert) {
+    assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN), 3, 'Expected [1, 2, NaN] to contain NaN');
+    assert.strictEqual(_.lastIndexOf([1, 2, Infinity], NaN), -1, 'Expected [1, 2, NaN] to contain NaN');
+
+    assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, 2), 2, 'fromIndex does not affect result');
+    assert.strictEqual(_.lastIndexOf([1, 2, NaN, NaN], NaN, -2), 2, 'fromIndex does not affect result');
+
+    (function() {
+      assert.strictEqual(_.lastIndexOf(arguments, NaN), 3, 'Expected arguments [1, 2, NaN] to contain NaN');
+    }(1, 2, NaN, NaN));
+  });
+
+  QUnit.test('lastIndexOf with +- 0', function(assert) {
+    _.each([-0, +0], function(val) {
+      assert.strictEqual(_.lastIndexOf([1, 2, val, val], val), 3);
+      assert.strictEqual(_.lastIndexOf([1, 2, val, val], -val), 3);
+      assert.strictEqual(_.lastIndexOf([-1, 1, 2], -val), -1);
+    });
+  });
+
+  QUnit.test('findIndex', function(assert) {
+    var objects = [
+      {a: 0, b: 0},
+      {a: 1, b: 1},
+      {a: 2, b: 2},
+      {a: 0, b: 0}
+    ];
+
+    assert.equal(_.findIndex(objects, function(obj) {
+      return obj.a === 0;
+    }), 0);
+
+    assert.equal(_.findIndex(objects, function(obj) {
+      return obj.b * obj.a === 4;
+    }), 2);
+
+    assert.equal(_.findIndex(objects, 'a'), 1, 'Uses lookupIterator');
+
+    assert.equal(_.findIndex(objects, function(obj) {
+      return obj.b * obj.a === 5;
+    }), -1);
+
+    assert.equal(_.findIndex(null, _.noop), -1);
+    assert.strictEqual(_.findIndex(objects, function(a) {
+      return a.foo === null;
+    }), -1);
+    _.findIndex([{a: 1}], function(a, key, obj) {
+      assert.equal(key, 0);
+      assert.deepEqual(obj, [{a: 1}]);
+      assert.strictEqual(this, objects, 'called with context');
+    }, objects);
+
+    var sparse = [];
+    sparse[20] = {a: 2, b: 2};
+    assert.equal(_.findIndex(sparse, function(obj) {
+      return obj && obj.b * obj.a === 4;
+    }), 20, 'Works with sparse arrays');
+
+    var array = [1, 2, 3, 4];
+    array.match = 55;
+    assert.strictEqual(_.findIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
+  });
+
+  QUnit.test('findLastIndex', function(assert) {
+    var objects = [
+      {a: 0, b: 0},
+      {a: 1, b: 1},
+      {a: 2, b: 2},
+      {a: 0, b: 0}
+    ];
+
+    assert.equal(_.findLastIndex(objects, function(obj) {
+      return obj.a === 0;
+    }), 3);
+
+    assert.equal(_.findLastIndex(objects, function(obj) {
+      return obj.b * obj.a === 4;
+    }), 2);
+
+    assert.equal(_.findLastIndex(objects, 'a'), 2, 'Uses lookupIterator');
+
+    assert.equal(_.findLastIndex(objects, function(obj) {
+      return obj.b * obj.a === 5;
+    }), -1);
+
+    assert.equal(_.findLastIndex(null, _.noop), -1);
+    assert.strictEqual(_.findLastIndex(objects, function(a) {
+      return a.foo === null;
+    }), -1);
+    _.findLastIndex([{a: 1}], function(a, key, obj) {
+      assert.equal(key, 0);
+      assert.deepEqual(obj, [{a: 1}]);
+      assert.strictEqual(this, objects, 'called with context');
+    }, objects);
+
+    var sparse = [];
+    sparse[20] = {a: 2, b: 2};
+    assert.equal(_.findLastIndex(sparse, function(obj) {
+      return obj && obj.b * obj.a === 4;
+    }), 20, 'Works with sparse arrays');
+
+    var array = [1, 2, 3, 4];
+    array.match = 55;
+    assert.strictEqual(_.findLastIndex(array, function(x) { return x === 55; }), -1, 'doesn\'t match array-likes keys');
+  });
+
+  QUnit.test('range', function(assert) {
+    assert.deepEqual(_.range(0), [], 'range with 0 as a first argument generates an empty array');
+    assert.deepEqual(_.range(4), [0, 1, 2, 3], 'range with a single positive argument generates an array of elements 0,1,2,...,n-1');
+    assert.deepEqual(_.range(5, 8), [5, 6, 7], 'range with two arguments a &amp; b, a&lt;b generates an array of elements a,a+1,a+2,...,b-2,b-1');
+    assert.deepEqual(_.range(3, 10, 3), [3, 6, 9], 'range with three arguments a &amp; b &amp; c, c &lt; b-a, a &lt; b generates an array of elements a,a+c,a+2c,...,b - (multiplier of a) &lt; c');
+    assert.deepEqual(_.range(3, 10, 15), [3], 'range with three arguments a &amp; b &amp; c, c &gt; b-a, a &lt; b generates an array with a single element, equal to a');
+    assert.deepEqual(_.range(12, 7, -2), [12, 10, 8], 'range with three arguments a &amp; b &amp; c, a &gt; b, c &lt; 0 generates an array of elements a,a-c,a-2c and ends with the number not less than b');
+    assert.deepEqual(_.range(0, -10, -1), [0, -1, -2, -3, -4, -5, -6, -7, -8, -9], 'final example in the Python docs');
+    assert.strictEqual(1 / _.range(-0, 1)[0], -Infinity, 'should preserve -0');
+    assert.deepEqual(_.range(8, 5), [8, 7, 6], 'negative range generates descending array');
+    assert.deepEqual(_.range(-3), [0, -1, -2], 'negative range generates descending array');
+  });
+
+  QUnit.test('chunk', function(assert) {
+    assert.deepEqual(_.chunk([], 2), [], 'chunk for empty array returns an empty array');
+
+    assert.deepEqual(_.chunk([1, 2, 3], 0), [], 'chunk into parts of 0 elements returns empty array');
+    assert.deepEqual(_.chunk([1, 2, 3], -1), [], 'chunk into parts of negative amount of elements returns an empty array');
+    assert.deepEqual(_.chunk([1, 2, 3]), [], 'defaults to empty array (chunk size 0)');
+
+    assert.deepEqual(_.chunk([1, 2, 3], 1), [[1], [2], [3]], 'chunk into parts of 1 elements returns original array');
+
+    assert.deepEqual(_.chunk([1, 2, 3], 3), [[1, 2, 3]], 'chunk into parts of current array length elements returns the original array');
+    assert.deepEqual(_.chunk([1, 2, 3], 5), [[1, 2, 3]], 'chunk into parts of more then current array length elements returns the original array');
+
+    assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 2), [[10, 20], [30, 40], [50, 60], [70]], 'chunk into parts of less then current array length elements');
+    assert.deepEqual(_.chunk([10, 20, 30, 40, 50, 60, 70], 3), [[10, 20, 30], [40, 50, 60], [70]], 'chunk into parts of less then current array length elements');
+  });
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/chaining.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/chaining.js
new file mode 100644
index 0000000..6ad21dc
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/chaining.js
@@ -0,0 +1,99 @@
+(function() {
+  var _ = typeof require == 'function' ? require('..') : window._;
+
+  QUnit.module('Chaining');
+
+  QUnit.test('map/flatten/reduce', function(assert) {
+    var lyrics = [
+      'I\'m a lumberjack and I\'m okay',
+      'I sleep all night and I work all day',
+      'He\'s a lumberjack and he\'s okay',
+      'He sleeps all night and he works all day'
+    ];
+    var counts = _(lyrics).chain()
+      .map(function(line) { return line.split(''); })
+      .flatten()
+      .reduce(function(hash, l) {
+        hash[l] = hash[l] || 0;
+        hash[l]++;
+        return hash;
+      }, {})
+      .value();
+    assert.equal(counts.a, 16, 'counted all the letters in the song');
+    assert.equal(counts.e, 10, 'counted all the letters in the song');
+  });
+
+  QUnit.test('select/reject/sortBy', function(assert) {
+    var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    numbers = _(numbers).chain().select(function(n) {
+      return n % 2 === 0;
+    }).reject(function(n) {
+      return n % 4 === 0;
+    }).sortBy(function(n) {
+      return -n;
+    }).value();
+    assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
+  });
+
+  QUnit.test('select/reject/sortBy in functional style', function(assert) {
+    var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    numbers = _.chain(numbers).select(function(n) {
+      return n % 2 === 0;
+    }).reject(function(n) {
+      return n % 4 === 0;
+    }).sortBy(function(n) {
+      return -n;
+    }).value();
+    assert.deepEqual(numbers, [10, 6, 2], 'filtered and reversed the numbers');
+  });
+
+  QUnit.test('reverse/concat/unshift/pop/map', function(assert) {
+    var numbers = [1, 2, 3, 4, 5];
+    numbers = _(numbers).chain()
+      .reverse()
+      .concat([5, 5, 5])
+      .unshift(17)
+      .pop()
+      .map(function(n){ return n * 2; })
+      .value();
+    assert.deepEqual(numbers, [34, 10, 8, 6, 4, 2, 10, 10], 'can chain together array functions.');
+  });
+
+  QUnit.test('splice', function(assert) {
+    var instance = _([1, 2, 3, 4, 5]).chain();
+    assert.deepEqual(instance.splice(1, 3).value(), [1, 5]);
+    assert.deepEqual(instance.splice(1, 0).value(), [1, 5]);
+    assert.deepEqual(instance.splice(1, 1).value(), [1]);
+    assert.deepEqual(instance.splice(0, 1).value(), [], '#397 Can create empty array');
+  });
+
+  QUnit.test('shift', function(assert) {
+    var instance = _([1, 2, 3]).chain();
+    assert.deepEqual(instance.shift().value(), [2, 3]);
+    assert.deepEqual(instance.shift().value(), [3]);
+    assert.deepEqual(instance.shift().value(), [], '#397 Can create empty array');
+  });
+
+  QUnit.test('pop', function(assert) {
+    var instance = _([1, 2, 3]).chain();
+    assert.deepEqual(instance.pop().value(), [1, 2]);
+    assert.deepEqual(instance.pop().value(), [1]);
+    assert.deepEqual(instance.pop().value(), [], '#397 Can create empty array');
+  });
+
+  QUnit.test('chaining works in small stages', function(assert) {
+    var o = _([1, 2, 3, 4]).chain();
+    assert.deepEqual(o.filter(function(i) { return i < 3; }).value(), [1, 2]);
+    assert.deepEqual(o.filter(function(i) { return i > 2; }).value(), [3, 4]);
+  });
+
+  QUnit.test('#1562: Engine proxies for chained functions', function(assert) {
+    var wrapped = _(512);
+    assert.strictEqual(wrapped.toJSON(), 512);
+    assert.strictEqual(wrapped.valueOf(), 512);
+    assert.strictEqual(+wrapped, 512);
+    assert.strictEqual(wrapped.toString(), '512');
+    assert.strictEqual('' + wrapped, '512');
+  });
+
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/collections.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/collections.js
new file mode 100644
index 0000000..182f7a2
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/collections.js
@@ -0,0 +1,896 @@
+(function() {
+  var _ = typeof require == 'function' ? require('..') : window._;
+
+  QUnit.module('Collections');
+
+  QUnit.test('each', function(assert) {
+    _.each([1, 2, 3], function(num, i) {
+      assert.equal(num, i + 1, 'each iterators provide value and iteration count');
+    });
+
+    var answers = [];
+    _.each([1, 2, 3], function(num){ answers.push(num * this.multiplier); }, {multiplier: 5});
+    assert.deepEqual(answers, [5, 10, 15], 'context object property accessed');
+
+    answers = [];
+    _.each([1, 2, 3], function(num){ answers.push(num); });
+    assert.deepEqual(answers, [1, 2, 3], 'can iterate a simple array');
+
+    answers = [];
+    var obj = {one: 1, two: 2, three: 3};
+    obj.constructor.prototype.four = 4;
+    _.each(obj, function(value, key){ answers.push(key); });
+    assert.deepEqual(answers, ['one', 'two', 'three'], 'iterating over objects works, and ignores the object prototype.');
+    delete obj.constructor.prototype.four;
+
+    // ensure the each function is JITed
+    _(1000).times(function() { _.each([], function(){}); });
+    var count = 0;
+    obj = {1: 'foo', 2: 'bar', 3: 'baz'};
+    _.each(obj, function(){ count++; });
+    assert.equal(count, 3, 'the fun should be called only 3 times');
+
+    var answer = null;
+    _.each([1, 2, 3], function(num, index, arr){ if (_.include(arr, num)) answer = true; });
+    assert.ok(answer, 'can reference the original collection from inside the iterator');
+
+    answers = 0;
+    _.each(null, function(){ ++answers; });
+    assert.equal(answers, 0, 'handles a null properly');
+
+    _.each(false, function(){});
+
+    var a = [1, 2, 3];
+    assert.strictEqual(_.each(a, function(){}), a);
+    assert.strictEqual(_.each(null, function(){}), null);
+  });
+
+  QUnit.test('forEach', function(assert) {
+    assert.strictEqual(_.forEach, _.each, 'is an alias for each');
+  });
+
+  QUnit.test('lookupIterator with contexts', function(assert) {
+    _.each([true, false, 'yes', '', 0, 1, {}], function(context) {
+      _.each([1], function() {
+        assert.equal(this, context);
+      }, context);
+    });
+  });
+
+  QUnit.test('Iterating objects with sketchy length properties', function(assert) {
+    var functions = [
+      'each', 'map', 'filter', 'find',
+      'some', 'every', 'max', 'min',
+      'groupBy', 'countBy', 'partition', 'indexBy'
+    ];
+    var reducers = ['reduce', 'reduceRight'];
+
+    var tricks = [
+      {length: '5'},
+      {length: {valueOf: _.constant(5)}},
+      {length: Math.pow(2, 53) + 1},
+      {length: Math.pow(2, 53)},
+      {length: null},
+      {length: -2},
+      {length: new Number(15)}
+    ];
+
+    assert.expect(tricks.length * (functions.length + reducers.length + 4));
+
+    _.each(tricks, function(trick) {
+      var length = trick.length;
+      assert.strictEqual(_.size(trick), 1, 'size on obj with length: ' + length);
+      assert.deepEqual(_.toArray(trick), [length], 'toArray on obj with length: ' + length);
+      assert.deepEqual(_.shuffle(trick), [length], 'shuffle on obj with length: ' + length);
+      assert.deepEqual(_.sample(trick), length, 'sample on obj with length: ' + length);
+
+
+      _.each(functions, function(method) {
+        _[method](trick, function(val, key) {
+          assert.strictEqual(key, 'length', method + ': ran with length = ' + val);
+        });
+      });
+
+      _.each(reducers, function(method) {
+        assert.strictEqual(_[method](trick), trick.length, method);
+      });
+    });
+  });
+
+  QUnit.test('Resistant to collection length and properties changing while iterating', function(assert) {
+
+    var collection = [
+      'each', 'map', 'filter', 'find',
+      'some', 'every', 'max', 'min', 'reject',
+      'groupBy', 'countBy', 'partition', 'indexBy',
+      'reduce', 'reduceRight'
+    ];
+    var array = [
+      'findIndex', 'findLastIndex'
+    ];
+    var object = [
+      'mapObject', 'findKey', 'pick', 'omit'
+    ];
+
+    _.each(collection.concat(array), function(method) {
+      var sparseArray = [1, 2, 3];
+      sparseArray.length = 100;
+      var answers = 0;
+      _[method](sparseArray, function(){
+        ++answers;
+        return method === 'every' ? true : null;
+      }, {});
+      assert.equal(answers, 100, method + ' enumerates [0, length)');
+
+      var growingCollection = [1, 2, 3], count = 0;
+      _[method](growingCollection, function() {
+        if (count < 10) growingCollection.push(count++);
+        return method === 'every' ? true : null;
+      }, {});
+      assert.equal(count, 3, method + ' is resistant to length changes');
+    });
+
+    _.each(collection.concat(object), function(method) {
+      var changingObject = {0: 0, 1: 1}, count = 0;
+      _[method](changingObject, function(val) {
+        if (count < 10) changingObject[++count] = val + 1;
+        return method === 'every' ? true : null;
+      }, {});
+
+      assert.equal(count, 2, method + ' is resistant to property changes');
+    });
+  });
+
+  QUnit.test('map', function(assert) {
+    var doubled = _.map([1, 2, 3], function(num){ return num * 2; });
+    assert.deepEqual(doubled, [2, 4, 6], 'doubled numbers');
+
+    var tripled = _.map([1, 2, 3], function(num){ return num * this.multiplier; }, {multiplier: 3});
+    assert.deepEqual(tripled, [3, 6, 9], 'tripled numbers with context');
+
+    doubled = _([1, 2, 3]).map(function(num){ return num * 2; });
+    assert.deepEqual(doubled, [2, 4, 6], 'OO-style doubled numbers');
+
+    var ids = _.map({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){
+      return n.id;
+    });
+    assert.deepEqual(ids, ['1', '2'], 'Can use collection methods on Array-likes.');
+
+    assert.deepEqual(_.map(null, _.noop), [], 'handles a null properly');
+
+    assert.deepEqual(_.map([1], function() {
+      return this.length;
+    }, [5]), [1], 'called with context');
+
+    // Passing a property name like _.pluck.
+    var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}];
+    assert.deepEqual(_.map(people, 'name'), ['moe', 'curly'], 'predicate string map to object properties');
+  });
+
+  QUnit.test('collect', function(assert) {
+    assert.strictEqual(_.collect, _.map, 'is an alias for map');
+  });
+
+  QUnit.test('reduce', function(assert) {
+    var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);
+    assert.equal(sum, 6, 'can sum up an array');
+
+    var context = {multiplier: 3};
+    sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num * this.multiplier; }, 0, context);
+    assert.equal(sum, 18, 'can reduce with a context object');
+
+    sum = _([1, 2, 3]).reduce(function(memo, num){ return memo + num; }, 0);
+    assert.equal(sum, 6, 'OO-style reduce');
+
+    sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; });
+    assert.equal(sum, 6, 'default initial value');
+
+    var prod = _.reduce([1, 2, 3, 4], function(memo, num){ return memo * num; });
+    assert.equal(prod, 24, 'can reduce via multiplication');
+
+    assert.ok(_.reduce(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
+    assert.equal(_.reduce([], _.noop, void 0), void 0, 'undefined can be passed as a special case');
+    assert.equal(_.reduce([_], _.noop), _, 'collection of length one with no initial value returns the first item');
+    assert.equal(_.reduce([], _.noop), void 0, 'returns undefined when collection is empty and no initial value');
+  });
+
+  QUnit.test('foldl', function(assert) {
+    assert.strictEqual(_.foldl, _.reduce, 'is an alias for reduce');
+  });
+
+  QUnit.test('inject', function(assert) {
+    assert.strictEqual(_.inject, _.reduce, 'is an alias for reduce');
+  });
+
+  QUnit.test('reduceRight', function(assert) {
+    var list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; }, '');
+    assert.equal(list, 'bazbarfoo', 'can perform right folds');
+
+    list = _.reduceRight(['foo', 'bar', 'baz'], function(memo, str){ return memo + str; });
+    assert.equal(list, 'bazbarfoo', 'default initial value');
+
+    var sum = _.reduceRight({a: 1, b: 2, c: 3}, function(memo, num){ return memo + num; });
+    assert.equal(sum, 6, 'default initial value on object');
+
+    assert.ok(_.reduceRight(null, _.noop, 138) === 138, 'handles a null (with initial value) properly');
+    assert.equal(_.reduceRight([_], _.noop), _, 'collection of length one with no initial value returns the first item');
+
+    assert.equal(_.reduceRight([], _.noop, void 0), void 0, 'undefined can be passed as a special case');
+    assert.equal(_.reduceRight([], _.noop), void 0, 'returns undefined when collection is empty and no initial value');
+
+    // Assert that the correct arguments are being passed.
+
+    var args,
+        init = {},
+        object = {a: 1, b: 2},
+        lastKey = _.keys(object).pop();
+
+    var expected = lastKey === 'a'
+      ? [init, 1, 'a', object]
+      : [init, 2, 'b', object];
+
+    _.reduceRight(object, function() {
+      if (!args) args = _.toArray(arguments);
+    }, init);
+
+    assert.deepEqual(args, expected);
+
+    // And again, with numeric keys.
+
+    object = {2: 'a', 1: 'b'};
+    lastKey = _.keys(object).pop();
+    args = null;
+
+    expected = lastKey === '2'
+      ? [init, 'a', '2', object]
+      : [init, 'b', '1', object];
+
+    _.reduceRight(object, function() {
+      if (!args) args = _.toArray(arguments);
+    }, init);
+
+    assert.deepEqual(args, expected);
+  });
+
+  QUnit.test('foldr', function(assert) {
+    assert.strictEqual(_.foldr, _.reduceRight, 'is an alias for reduceRight');
+  });
+
+  QUnit.test('find', function(assert) {
+    var array = [1, 2, 3, 4];
+    assert.strictEqual(_.find(array, function(n) { return n > 2; }), 3, 'should return first found `value`');
+    assert.strictEqual(_.find(array, function() { return false; }), void 0, 'should return `undefined` if `value` is not found');
+
+    array.dontmatch = 55;
+    assert.strictEqual(_.find(array, function(x) { return x === 55; }), void 0, 'iterates array-likes correctly');
+
+    // Matching an object like _.findWhere.
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
+    assert.deepEqual(_.find(list, {a: 1}), {a: 1, b: 2}, 'can be used as findWhere');
+    assert.deepEqual(_.find(list, {b: 4}), {a: 1, b: 4});
+    assert.ok(!_.find(list, {c: 1}), 'undefined when not found');
+    assert.ok(!_.find([], {c: 1}), 'undefined when searching empty list');
+
+    var result = _.find([1, 2, 3], function(num){ return num * 2 === 4; });
+    assert.equal(result, 2, 'found the first "2" and broke the loop');
+
+    var obj = {
+      a: {x: 1, z: 3},
+      b: {x: 2, z: 2},
+      c: {x: 3, z: 4},
+      d: {x: 4, z: 1}
+    };
+
+    assert.deepEqual(_.find(obj, {x: 2}), {x: 2, z: 2}, 'works on objects');
+    assert.deepEqual(_.find(obj, {x: 2, z: 1}), void 0);
+    assert.deepEqual(_.find(obj, function(x) {
+      return x.x === 4;
+    }), {x: 4, z: 1});
+
+    _.findIndex([{a: 1}], function(a, key, o) {
+      assert.equal(key, 0);
+      assert.deepEqual(o, [{a: 1}]);
+      assert.strictEqual(this, _, 'called with context');
+    }, _);
+  });
+
+  QUnit.test('detect', function(assert) {
+    assert.strictEqual(_.detect, _.find, 'is an alias for find');
+  });
+
+  QUnit.test('filter', function(assert) {
+    var evenArray = [1, 2, 3, 4, 5, 6];
+    var evenObject = {one: 1, two: 2, three: 3};
+    var isEven = function(num){ return num % 2 === 0; };
+
+    assert.deepEqual(_.filter(evenArray, isEven), [2, 4, 6]);
+    assert.deepEqual(_.filter(evenObject, isEven), [2], 'can filter objects');
+    assert.deepEqual(_.filter([{}, evenObject, []], 'two'), [evenObject], 'predicate string map to object properties');
+
+    _.filter([1], function() {
+      assert.equal(this, evenObject, 'given context');
+    }, evenObject);
+
+    // Can be used like _.where.
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
+    assert.deepEqual(_.filter(list, {a: 1}), [{a: 1, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}]);
+    assert.deepEqual(_.filter(list, {b: 2}), [{a: 1, b: 2}, {a: 2, b: 2}]);
+    assert.deepEqual(_.filter(list, {}), list, 'Empty object accepts all items');
+    assert.deepEqual(_(list).filter({}), list, 'OO-filter');
+  });
+
+  QUnit.test('select', function(assert) {
+    assert.strictEqual(_.select, _.filter, 'is an alias for filter');
+  });
+
+  QUnit.test('reject', function(assert) {
+    var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 === 0; });
+    assert.deepEqual(odds, [1, 3, 5], 'rejected each even number');
+
+    var context = 'obj';
+
+    var evens = _.reject([1, 2, 3, 4, 5, 6], function(num){
+      assert.equal(context, 'obj');
+      return num % 2 !== 0;
+    }, context);
+    assert.deepEqual(evens, [2, 4, 6], 'rejected each odd number');
+
+    assert.deepEqual(_.reject([odds, {one: 1, two: 2, three: 3}], 'two'), [odds], 'predicate string map to object properties');
+
+    // Can be used like _.where.
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
+    assert.deepEqual(_.reject(list, {a: 1}), [{a: 2, b: 2}]);
+    assert.deepEqual(_.reject(list, {b: 2}), [{a: 1, b: 3}, {a: 1, b: 4}]);
+    assert.deepEqual(_.reject(list, {}), [], 'Returns empty list given empty object');
+    assert.deepEqual(_.reject(list, []), [], 'Returns empty list given empty array');
+  });
+
+  QUnit.test('every', function(assert) {
+    assert.ok(_.every([], _.identity), 'the empty set');
+    assert.ok(_.every([true, true, true], _.identity), 'every true values');
+    assert.ok(!_.every([true, false, true], _.identity), 'one false value');
+    assert.ok(_.every([0, 10, 28], function(num){ return num % 2 === 0; }), 'even numbers');
+    assert.ok(!_.every([0, 11, 28], function(num){ return num % 2 === 0; }), 'an odd number');
+    assert.ok(_.every([1], _.identity) === true, 'cast to boolean - true');
+    assert.ok(_.every([0], _.identity) === false, 'cast to boolean - false');
+    assert.ok(!_.every([void 0, void 0, void 0], _.identity), 'works with arrays of undefined');
+
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
+    assert.ok(!_.every(list, {a: 1, b: 2}), 'Can be called with object');
+    assert.ok(_.every(list, 'a'), 'String mapped to object property');
+
+    list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}];
+    assert.ok(_.every(list, {b: 2}), 'Can be called with object');
+    assert.ok(!_.every(list, 'c'), 'String mapped to object property');
+
+    assert.ok(_.every({a: 1, b: 2, c: 3, d: 4}, _.isNumber), 'takes objects');
+    assert.ok(!_.every({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects');
+    assert.ok(_.every(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
+    assert.ok(!_.every(['a', 'b', 'c', 'd', 'f'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
+  });
+
+  QUnit.test('all', function(assert) {
+    assert.strictEqual(_.all, _.every, 'is an alias for every');
+  });
+
+  QUnit.test('some', function(assert) {
+    assert.ok(!_.some([]), 'the empty set');
+    assert.ok(!_.some([false, false, false]), 'all false values');
+    assert.ok(_.some([false, false, true]), 'one true value');
+    assert.ok(_.some([null, 0, 'yes', false]), 'a string');
+    assert.ok(!_.some([null, 0, '', false]), 'falsy values');
+    assert.ok(!_.some([1, 11, 29], function(num){ return num % 2 === 0; }), 'all odd numbers');
+    assert.ok(_.some([1, 10, 29], function(num){ return num % 2 === 0; }), 'an even number');
+    assert.ok(_.some([1], _.identity) === true, 'cast to boolean - true');
+    assert.ok(_.some([0], _.identity) === false, 'cast to boolean - false');
+    assert.ok(_.some([false, false, true]));
+
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
+    assert.ok(!_.some(list, {a: 5, b: 2}), 'Can be called with object');
+    assert.ok(_.some(list, 'a'), 'String mapped to object property');
+
+    list = [{a: 1, b: 2}, {a: 2, b: 2, c: true}];
+    assert.ok(_.some(list, {b: 2}), 'Can be called with object');
+    assert.ok(!_.some(list, 'd'), 'String mapped to object property');
+
+    assert.ok(_.some({a: '1', b: '2', c: '3', d: '4', e: 6}, _.isNumber), 'takes objects');
+    assert.ok(!_.some({a: 1, b: 2, c: 3, d: 4}, _.isObject), 'takes objects');
+    assert.ok(_.some(['a', 'b', 'c', 'd'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
+    assert.ok(!_.some(['x', 'y', 'z'], _.hasOwnProperty, {a: 1, b: 2, c: 3, d: 4}), 'context works');
+  });
+
+  QUnit.test('any', function(assert) {
+    assert.strictEqual(_.any, _.some, 'is an alias for some');
+  });
+
+  QUnit.test('includes', function(assert) {
+    _.each([null, void 0, 0, 1, NaN, {}, []], function(val) {
+      assert.strictEqual(_.includes(val, 'hasOwnProperty'), false);
+    });
+    assert.strictEqual(_.includes([1, 2, 3], 2), true, 'two is in the array');
+    assert.ok(!_.includes([1, 3, 9], 2), 'two is not in the array');
+
+    assert.strictEqual(_.includes([5, 4, 3, 2, 1], 5, true), true, 'doesn\'t delegate to binary search');
+
+    assert.ok(_.includes({moe: 1, larry: 3, curly: 9}, 3) === true, '_.includes on objects checks their values');
+    assert.ok(_([1, 2, 3]).includes(2), 'OO-style includes');
+
+    var numbers = [1, 2, 3, 1, 2, 3, 1, 2, 3];
+    assert.strictEqual(_.includes(numbers, 1, 1), true, 'takes a fromIndex');
+    assert.strictEqual(_.includes(numbers, 1, -1), false, 'takes a fromIndex');
+    assert.strictEqual(_.includes(numbers, 1, -2), false, 'takes a fromIndex');
+    assert.strictEqual(_.includes(numbers, 1, -3), true, 'takes a fromIndex');
+    assert.strictEqual(_.includes(numbers, 1, 6), true, 'takes a fromIndex');
+    assert.strictEqual(_.includes(numbers, 1, 7), false, 'takes a fromIndex');
+
+    assert.ok(_.every([1, 2, 3], _.partial(_.includes, numbers)), 'fromIndex is guarded');
+  });
+
+  QUnit.test('include', function(assert) {
+    assert.strictEqual(_.include, _.includes, 'is an alias for includes');
+  });
+
+  QUnit.test('contains', function(assert) {
+    assert.strictEqual(_.contains, _.includes, 'is an alias for includes');
+
+  });
+
+  QUnit.test('includes with NaN', function(assert) {
+    assert.strictEqual(_.includes([1, 2, NaN, NaN], NaN), true, 'Expected [1, 2, NaN] to contain NaN');
+    assert.strictEqual(_.includes([1, 2, Infinity], NaN), false, 'Expected [1, 2, NaN] to contain NaN');
+  });
+
+  QUnit.test('includes with +- 0', function(assert) {
+    _.each([-0, +0], function(val) {
+      assert.strictEqual(_.includes([1, 2, val, val], val), true);
+      assert.strictEqual(_.includes([1, 2, val, val], -val), true);
+      assert.strictEqual(_.includes([-1, 1, 2], -val), false);
+    });
+  });
+
+
+  QUnit.test('invoke', function(assert) {
+    assert.expect(5);
+    var list = [[5, 1, 7], [3, 2, 1]];
+    var result = _.invoke(list, 'sort');
+    assert.deepEqual(result[0], [1, 5, 7], 'first array sorted');
+    assert.deepEqual(result[1], [1, 2, 3], 'second array sorted');
+
+    _.invoke([{
+      method: function() {
+        assert.deepEqual(_.toArray(arguments), [1, 2, 3], 'called with arguments');
+      }
+    }], 'method', 1, 2, 3);
+
+    assert.deepEqual(_.invoke([{a: null}, {}, {a: _.constant(1)}], 'a'), [null, void 0, 1], 'handles null & undefined');
+
+    assert.raises(function() {
+      _.invoke([{a: 1}], 'a');
+    }, TypeError, 'throws for non-functions');
+  });
+
+  QUnit.test('invoke w/ function reference', function(assert) {
+    var list = [[5, 1, 7], [3, 2, 1]];
+    var result = _.invoke(list, Array.prototype.sort);
+    assert.deepEqual(result[0], [1, 5, 7], 'first array sorted');
+    assert.deepEqual(result[1], [1, 2, 3], 'second array sorted');
+
+    assert.deepEqual(_.invoke([1, 2, 3], function(a) {
+      return a + this;
+    }, 5), [6, 7, 8], 'receives params from invoke');
+  });
+
+  // Relevant when using ClojureScript
+  QUnit.test('invoke when strings have a call method', function(assert) {
+    String.prototype.call = function() {
+      return 42;
+    };
+    var list = [[5, 1, 7], [3, 2, 1]];
+    var s = 'foo';
+    assert.equal(s.call(), 42, 'call function exists');
+    var result = _.invoke(list, 'sort');
+    assert.deepEqual(result[0], [1, 5, 7], 'first array sorted');
+    assert.deepEqual(result[1], [1, 2, 3], 'second array sorted');
+    delete String.prototype.call;
+    assert.equal(s.call, void 0, 'call function removed');
+  });
+
+  QUnit.test('pluck', function(assert) {
+    var people = [{name: 'moe', age: 30}, {name: 'curly', age: 50}];
+    assert.deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'pulls names out of objects');
+    assert.deepEqual(_.pluck(people, 'address'), [void 0, void 0], 'missing properties are returned as undefined');
+    //compat: most flexible handling of edge cases
+    assert.deepEqual(_.pluck([{'[object Object]': 1}], {}), [1]);
+  });
+
+  QUnit.test('where', function(assert) {
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}];
+    var result = _.where(list, {a: 1});
+    assert.equal(result.length, 3);
+    assert.equal(result[result.length - 1].b, 4);
+    result = _.where(list, {b: 2});
+    assert.equal(result.length, 2);
+    assert.equal(result[0].a, 1);
+    result = _.where(list, {});
+    assert.equal(result.length, list.length);
+
+    function test() {}
+    test.map = _.map;
+    assert.deepEqual(_.where([_, {a: 1, b: 2}, _], test), [_, _], 'checks properties given function');
+  });
+
+  QUnit.test('findWhere', function(assert) {
+    var list = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 1, b: 3}, {a: 1, b: 4}, {a: 2, b: 4}];
+    var result = _.findWhere(list, {a: 1});
+    assert.deepEqual(result, {a: 1, b: 2});
+    result = _.findWhere(list, {b: 4});
+    assert.deepEqual(result, {a: 1, b: 4});
+
+    result = _.findWhere(list, {c: 1});
+    assert.ok(_.isUndefined(result), 'undefined when not found');
+
+    result = _.findWhere([], {c: 1});
+    assert.ok(_.isUndefined(result), 'undefined when searching empty list');
+
+    function test() {}
+    test.map = _.map;
+    assert.equal(_.findWhere([_, {a: 1, b: 2}, _], test), _, 'checks properties given function');
+
+    function TestClass() {
+      this.y = 5;
+      this.x = 'foo';
+    }
+    var expect = {c: 1, x: 'foo', y: 5};
+    assert.deepEqual(_.findWhere([{y: 5, b: 6}, expect], new TestClass()), expect, 'uses class instance properties');
+  });
+
+  QUnit.test('max', function(assert) {
+    assert.equal(-Infinity, _.max(null), 'can handle null/undefined');
+    assert.equal(-Infinity, _.max(void 0), 'can handle null/undefined');
+    assert.equal(-Infinity, _.max(null, _.identity), 'can handle null/undefined');
+
+    assert.equal(3, _.max([1, 2, 3]), 'can perform a regular Math.max');
+
+    var neg = _.max([1, 2, 3], function(num){ return -num; });
+    assert.equal(neg, 1, 'can perform a computation-based max');
+
+    assert.equal(-Infinity, _.max({}), 'Maximum value of an empty object');
+    assert.equal(-Infinity, _.max([]), 'Maximum value of an empty array');
+    assert.equal(_.max({a: 'a'}), -Infinity, 'Maximum value of a non-numeric collection');
+
+    assert.equal(299999, _.max(_.range(1, 300000)), 'Maximum value of a too-big array');
+
+    assert.equal(3, _.max([1, 2, 3, 'test']), 'Finds correct max in array starting with num and containing a NaN');
+    assert.equal(3, _.max(['test', 1, 2, 3]), 'Finds correct max in array starting with NaN');
+
+    assert.equal(3, _.max([1, 2, 3, null]), 'Finds correct max in array starting with num and containing a `null`');
+    assert.equal(3, _.max([null, 1, 2, 3]), 'Finds correct max in array starting with a `null`');
+
+    assert.equal(3, _.max([1, 2, 3, '']), 'Finds correct max in array starting with num and containing an empty string');
+    assert.equal(3, _.max(['', 1, 2, 3]), 'Finds correct max in array starting with an empty string');
+
+    assert.equal(3, _.max([1, 2, 3, false]), 'Finds correct max in array starting with num and containing a false');
+    assert.equal(3, _.max([false, 1, 2, 3]), 'Finds correct max in array starting with a false');
+
+    assert.equal(4, _.max([0, 1, 2, 3, 4]), 'Finds correct max in array containing a zero');
+    assert.equal(0, _.max([-3, -2, -1, 0]), 'Finds correct max in array containing negative numbers');
+
+    assert.deepEqual([3, 6], _.map([[1, 2, 3], [4, 5, 6]], _.max), 'Finds correct max in array when mapping through multiple arrays');
+
+    var a = {x: -Infinity};
+    var b = {x: -Infinity};
+    var iterator = function(o){ return o.x; };
+    assert.equal(_.max([a, b], iterator), a, 'Respects iterator return value of -Infinity');
+
+    assert.deepEqual(_.max([{a: 1}, {a: 0, b: 3}, {a: 4}, {a: 2}], 'a'), {a: 4}, 'String keys use property iterator');
+
+    assert.deepEqual(_.max([0, 2], function(c){ return c * this.x; }, {x: 1}), 2, 'Iterator context');
+    assert.deepEqual(_.max([[1], [2, 3], [-1, 4], [5]], 0), [5], 'Lookup falsy iterator');
+    assert.deepEqual(_.max([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: 2}, 'Lookup falsy iterator');
+  });
+
+  QUnit.test('min', function(assert) {
+    assert.equal(Infinity, _.min(null), 'can handle null/undefined');
+    assert.equal(Infinity, _.min(void 0), 'can handle null/undefined');
+    assert.equal(Infinity, _.min(null, _.identity), 'can handle null/undefined');
+
+    assert.equal(1, _.min([1, 2, 3]), 'can perform a regular Math.min');
+
+    var neg = _.min([1, 2, 3], function(num){ return -num; });
+    assert.equal(neg, 3, 'can perform a computation-based min');
+
+    assert.equal(Infinity, _.min({}), 'Minimum value of an empty object');
+    assert.equal(Infinity, _.min([]), 'Minimum value of an empty array');
+    assert.equal(_.min({a: 'a'}), Infinity, 'Minimum value of a non-numeric collection');
+
+    assert.deepEqual([1, 4], _.map([[1, 2, 3], [4, 5, 6]], _.min), 'Finds correct min in array when mapping through multiple arrays');
+
+    var now = new Date(9999999999);
+    var then = new Date(0);
+    assert.equal(_.min([now, then]), then);
+
+    assert.equal(1, _.min(_.range(1, 300000)), 'Minimum value of a too-big array');
+
+    assert.equal(1, _.min([1, 2, 3, 'test']), 'Finds correct min in array starting with num and containing a NaN');
+    assert.equal(1, _.min(['test', 1, 2, 3]), 'Finds correct min in array starting with NaN');
+
+    assert.equal(1, _.min([1, 2, 3, null]), 'Finds correct min in array starting with num and containing a `null`');
+    assert.equal(1, _.min([null, 1, 2, 3]), 'Finds correct min in array starting with a `null`');
+
+    assert.equal(0, _.min([0, 1, 2, 3, 4]), 'Finds correct min in array containing a zero');
+    assert.equal(-3, _.min([-3, -2, -1, 0]), 'Finds correct min in array containing negative numbers');
+
+    var a = {x: Infinity};
+    var b = {x: Infinity};
+    var iterator = function(o){ return o.x; };
+    assert.equal(_.min([a, b], iterator), a, 'Respects iterator return value of Infinity');
+
+    assert.deepEqual(_.min([{a: 1}, {a: 0, b: 3}, {a: 4}, {a: 2}], 'a'), {a: 0, b: 3}, 'String keys use property iterator');
+
+    assert.deepEqual(_.min([0, 2], function(c){ return c * this.x; }, {x: -1}), 2, 'Iterator context');
+    assert.deepEqual(_.min([[1], [2, 3], [-1, 4], [5]], 0), [-1, 4], 'Lookup falsy iterator');
+    assert.deepEqual(_.min([{0: 1}, {0: 2}, {0: -1}, {a: 1}], 0), {0: -1}, 'Lookup falsy iterator');
+  });
+
+  QUnit.test('sortBy', function(assert) {
+    var people = [{name: 'curly', age: 50}, {name: 'moe', age: 30}];
+    people = _.sortBy(people, function(person){ return person.age; });
+    assert.deepEqual(_.pluck(people, 'name'), ['moe', 'curly'], 'stooges sorted by age');
+
+    var list = [void 0, 4, 1, void 0, 3, 2];
+    assert.deepEqual(_.sortBy(list, _.identity), [1, 2, 3, 4, void 0, void 0], 'sortBy with undefined values');
+
+    list = ['one', 'two', 'three', 'four', 'five'];
+    var sorted = _.sortBy(list, 'length');
+    assert.deepEqual(sorted, ['one', 'two', 'four', 'five', 'three'], 'sorted by length');
+
+    function Pair(x, y) {
+      this.x = x;
+      this.y = y;
+    }
+
+    var stableArray = [
+      new Pair(1, 1), new Pair(1, 2),
+      new Pair(1, 3), new Pair(1, 4),
+      new Pair(1, 5), new Pair(1, 6),
+      new Pair(2, 1), new Pair(2, 2),
+      new Pair(2, 3), new Pair(2, 4),
+      new Pair(2, 5), new Pair(2, 6),
+      new Pair(void 0, 1), new Pair(void 0, 2),
+      new Pair(void 0, 3), new Pair(void 0, 4),
+      new Pair(void 0, 5), new Pair(void 0, 6)
+    ];
+
+    var stableObject = _.object('abcdefghijklmnopqr'.split(''), stableArray);
+
+    var actual = _.sortBy(stableArray, function(pair) {
+      return pair.x;
+    });
+
+    assert.deepEqual(actual, stableArray, 'sortBy should be stable for arrays');
+    assert.deepEqual(_.sortBy(stableArray, 'x'), stableArray, 'sortBy accepts property string');
+
+    actual = _.sortBy(stableObject, function(pair) {
+      return pair.x;
+    });
+
+    assert.deepEqual(actual, stableArray, 'sortBy should be stable for objects');
+
+    list = ['q', 'w', 'e', 'r', 't', 'y'];
+    assert.deepEqual(_.sortBy(list), ['e', 'q', 'r', 't', 'w', 'y'], 'uses _.identity if iterator is not specified');
+  });
+
+  QUnit.test('groupBy', function(assert) {
+    var parity = _.groupBy([1, 2, 3, 4, 5, 6], function(num){ return num % 2; });
+    assert.ok('0' in parity && '1' in parity, 'created a group for each value');
+    assert.deepEqual(parity[0], [2, 4, 6], 'put each even number in the right group');
+
+    var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
+    var grouped = _.groupBy(list, 'length');
+    assert.deepEqual(grouped['3'], ['one', 'two', 'six', 'ten']);
+    assert.deepEqual(grouped['4'], ['four', 'five', 'nine']);
+    assert.deepEqual(grouped['5'], ['three', 'seven', 'eight']);
+
+    var context = {};
+    _.groupBy([{}], function(){ assert.ok(this === context); }, context);
+
+    grouped = _.groupBy([4.2, 6.1, 6.4], function(num) {
+      return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
+    });
+    assert.equal(grouped.constructor.length, 1);
+    assert.equal(grouped.hasOwnProperty.length, 2);
+
+    var array = [{}];
+    _.groupBy(array, function(value, index, obj){ assert.ok(obj === array); });
+
+    array = [1, 2, 1, 2, 3];
+    grouped = _.groupBy(array);
+    assert.equal(grouped['1'].length, 2);
+    assert.equal(grouped['3'].length, 1);
+
+    var matrix = [
+      [1, 2],
+      [1, 3],
+      [2, 3]
+    ];
+    assert.deepEqual(_.groupBy(matrix, 0), {1: [[1, 2], [1, 3]], 2: [[2, 3]]});
+    assert.deepEqual(_.groupBy(matrix, 1), {2: [[1, 2]], 3: [[1, 3], [2, 3]]});
+  });
+
+  QUnit.test('indexBy', function(assert) {
+    var parity = _.indexBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; });
+    assert.equal(parity['true'], 4);
+    assert.equal(parity['false'], 5);
+
+    var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
+    var grouped = _.indexBy(list, 'length');
+    assert.equal(grouped['3'], 'ten');
+    assert.equal(grouped['4'], 'nine');
+    assert.equal(grouped['5'], 'eight');
+
+    var array = [1, 2, 1, 2, 3];
+    grouped = _.indexBy(array);
+    assert.equal(grouped['1'], 1);
+    assert.equal(grouped['2'], 2);
+    assert.equal(grouped['3'], 3);
+  });
+
+  QUnit.test('countBy', function(assert) {
+    var parity = _.countBy([1, 2, 3, 4, 5], function(num){ return num % 2 === 0; });
+    assert.equal(parity['true'], 2);
+    assert.equal(parity['false'], 3);
+
+    var list = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten'];
+    var grouped = _.countBy(list, 'length');
+    assert.equal(grouped['3'], 4);
+    assert.equal(grouped['4'], 3);
+    assert.equal(grouped['5'], 3);
+
+    var context = {};
+    _.countBy([{}], function(){ assert.ok(this === context); }, context);
+
+    grouped = _.countBy([4.2, 6.1, 6.4], function(num) {
+      return Math.floor(num) > 4 ? 'hasOwnProperty' : 'constructor';
+    });
+    assert.equal(grouped.constructor, 1);
+    assert.equal(grouped.hasOwnProperty, 2);
+
+    var array = [{}];
+    _.countBy(array, function(value, index, obj){ assert.ok(obj === array); });
+
+    array = [1, 2, 1, 2, 3];
+    grouped = _.countBy(array);
+    assert.equal(grouped['1'], 2);
+    assert.equal(grouped['3'], 1);
+  });
+
+  QUnit.test('shuffle', function(assert) {
+    assert.deepEqual(_.shuffle([1]), [1], 'behaves correctly on size 1 arrays');
+    var numbers = _.range(20);
+    var shuffled = _.shuffle(numbers);
+    assert.notDeepEqual(numbers, shuffled, 'does change the order'); // Chance of false negative: 1 in ~2.4*10^18
+    assert.notStrictEqual(numbers, shuffled, 'original object is unmodified');
+    assert.deepEqual(numbers, _.sortBy(shuffled), 'contains the same members before and after shuffle');
+
+    shuffled = _.shuffle({a: 1, b: 2, c: 3, d: 4});
+    assert.equal(shuffled.length, 4);
+    assert.deepEqual(shuffled.sort(), [1, 2, 3, 4], 'works on objects');
+  });
+
+  QUnit.test('sample', function(assert) {
+    assert.strictEqual(_.sample([1]), 1, 'behaves correctly when no second parameter is given');
+    assert.deepEqual(_.sample([1, 2, 3], -2), [], 'behaves correctly on negative n');
+    var numbers = _.range(10);
+    var allSampled = _.sample(numbers, 10).sort();
+    assert.deepEqual(allSampled, numbers, 'contains the same members before and after sample');
+    allSampled = _.sample(numbers, 20).sort();
+    assert.deepEqual(allSampled, numbers, 'also works when sampling more objects than are present');
+    assert.ok(_.contains(numbers, _.sample(numbers)), 'sampling a single element returns something from the array');
+    assert.strictEqual(_.sample([]), void 0, 'sampling empty array with no number returns undefined');
+    assert.notStrictEqual(_.sample([], 5), [], 'sampling empty array with a number returns an empty array');
+    assert.notStrictEqual(_.sample([1, 2, 3], 0), [], 'sampling an array with 0 picks returns an empty array');
+    assert.deepEqual(_.sample([1, 2], -1), [], 'sampling a negative number of picks returns an empty array');
+    assert.ok(_.contains([1, 2, 3], _.sample({a: 1, b: 2, c: 3})), 'sample one value from an object');
+    var partialSample = _.sample(_.range(1000), 10);
+    var partialSampleSorted = partialSample.sort();
+    assert.notDeepEqual(partialSampleSorted, _.range(10), 'samples from the whole array, not just the beginning');
+  });
+
+  QUnit.test('toArray', function(assert) {
+    assert.ok(!_.isArray(arguments), 'arguments object is not an array');
+    assert.ok(_.isArray(_.toArray(arguments)), 'arguments object converted into array');
+    var a = [1, 2, 3];
+    assert.ok(_.toArray(a) !== a, 'array is cloned');
+    assert.deepEqual(_.toArray(a), [1, 2, 3], 'cloned array contains same elements');
+
+    var numbers = _.toArray({one: 1, two: 2, three: 3});
+    assert.deepEqual(numbers, [1, 2, 3], 'object flattened into array');
+
+    var hearts = '\uD83D\uDC95';
+    var pair = hearts.split('');
+    var expected = [pair[0], hearts, '&', hearts, pair[1]];
+    assert.deepEqual(_.toArray(expected.join('')), expected, 'maintains astral characters');
+    assert.deepEqual(_.toArray(''), [], 'empty string into empty array');
+
+    if (typeof document != 'undefined') {
+      // test in IE < 9
+      var actual;
+      try {
+        actual = _.toArray(document.childNodes);
+      } catch (e) { /* ignored */ }
+      assert.deepEqual(actual, _.map(document.childNodes, _.identity), 'works on NodeList');
+    }
+  });
+
+  QUnit.test('size', function(assert) {
+    assert.equal(_.size({one: 1, two: 2, three: 3}), 3, 'can compute the size of an object');
+    assert.equal(_.size([1, 2, 3]), 3, 'can compute the size of an array');
+    assert.equal(_.size({length: 3, 0: 0, 1: 0, 2: 0}), 3, 'can compute the size of Array-likes');
+
+    var func = function() {
+      return _.size(arguments);
+    };
+
+    assert.equal(func(1, 2, 3, 4), 4, 'can test the size of the arguments object');
+
+    assert.equal(_.size('hello'), 5, 'can compute the size of a string literal');
+    assert.equal(_.size(new String('hello')), 5, 'can compute the size of string object');
+
+    assert.equal(_.size(null), 0, 'handles nulls');
+    assert.equal(_.size(0), 0, 'handles numbers');
+  });
+
+  QUnit.test('partition', function(assert) {
+    var list = [0, 1, 2, 3, 4, 5];
+    assert.deepEqual(_.partition(list, function(x) { return x < 4; }), [[0, 1, 2, 3], [4, 5]], 'handles bool return values');
+    assert.deepEqual(_.partition(list, function(x) { return x & 1; }), [[1, 3, 5], [0, 2, 4]], 'handles 0 and 1 return values');
+    assert.deepEqual(_.partition(list, function(x) { return x - 3; }), [[0, 1, 2, 4, 5], [3]], 'handles other numeric return values');
+    assert.deepEqual(_.partition(list, function(x) { return x > 1 ? null : true; }), [[0, 1], [2, 3, 4, 5]], 'handles null return values');
+    assert.deepEqual(_.partition(list, function(x) { if (x < 2) return true; }), [[0, 1], [2, 3, 4, 5]], 'handles undefined return values');
+    assert.deepEqual(_.partition({a: 1, b: 2, c: 3}, function(x) { return x > 1; }), [[2, 3], [1]], 'handles objects');
+
+    assert.deepEqual(_.partition(list, function(x, index) { return index % 2; }), [[1, 3, 5], [0, 2, 4]], 'can reference the array index');
+    assert.deepEqual(_.partition(list, function(x, index, arr) { return x === arr.length - 1; }), [[5], [0, 1, 2, 3, 4]], 'can reference the collection');
+
+    // Default iterator
+    assert.deepEqual(_.partition([1, false, true, '']), [[1, true], [false, '']], 'Default iterator');
+    assert.deepEqual(_.partition([{x: 1}, {x: 0}, {x: 1}], 'x'), [[{x: 1}, {x: 1}], [{x: 0}]], 'Takes a string');
+
+    // Context
+    var predicate = function(x){ return x === this.x; };
+    assert.deepEqual(_.partition([1, 2, 3], predicate, {x: 2}), [[2], [1, 3]], 'partition takes a context argument');
+
+    assert.deepEqual(_.partition([{a: 1}, {b: 2}, {a: 1, b: 2}], {a: 1}), [[{a: 1}, {a: 1, b: 2}], [{b: 2}]], 'predicate can be object');
+
+    var object = {a: 1};
+    _.partition(object, function(val, key, obj) {
+      assert.equal(val, 1);
+      assert.equal(key, 'a');
+      assert.equal(obj, object);
+      assert.equal(this, predicate);
+    }, predicate);
+  });
+
+  if (typeof document != 'undefined') {
+    QUnit.test('Can use various collection methods on NodeLists', function(assert) {
+      var parent = document.createElement('div');
+      parent.innerHTML = '<span id=id1></span>textnode<span id=id2></span>';
+
+      var elementChildren = _.filter(parent.childNodes, _.isElement);
+      assert.equal(elementChildren.length, 2);
+
+      assert.deepEqual(_.map(elementChildren, 'id'), ['id1', 'id2']);
+      assert.deepEqual(_.map(parent.childNodes, 'nodeType'), [1, 3, 1]);
+
+      assert.ok(!_.every(parent.childNodes, _.isElement));
+      assert.ok(_.some(parent.childNodes, _.isElement));
+
+      function compareNode(node) {
+        return _.isElement(node) ? node.id.charAt(2) : void 0;
+      }
+      assert.equal(_.max(parent.childNodes, compareNode), _.last(parent.childNodes));
+      assert.equal(_.min(parent.childNodes, compareNode), _.first(parent.childNodes));
+    });
+  }
+
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/cross-document.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/cross-document.js
new file mode 100644
index 0000000..cb68a3d
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/cross-document.js
@@ -0,0 +1,141 @@
+(function() {
+  if (typeof document == 'undefined') return;
+
+  var _ = typeof require == 'function' ? require('..') : window._;
+
+  QUnit.module('Cross Document');
+  /* global iObject, iElement, iArguments, iFunction, iArray, iError, iString, iNumber, iBoolean, iDate, iRegExp, iNaN, iNull, iUndefined, ActiveXObject */
+
+  // Setup remote variables for iFrame tests.
+  var iframe = document.createElement('iframe');
+  iframe.frameBorder = iframe.height = iframe.width = 0;
+  document.body.appendChild(iframe);
+  var iDoc = (iDoc = iframe.contentDocument || iframe.contentWindow).document || iDoc;
+  iDoc.write(
+    [
+      '<script>',
+      'parent.iElement = document.createElement("div");',
+      'parent.iArguments = (function(){ return arguments; })(1, 2, 3);',
+      'parent.iArray = [1, 2, 3];',
+      'parent.iString = new String("hello");',
+      'parent.iNumber = new Number(100);',
+      'parent.iFunction = (function(){});',
+      'parent.iDate = new Date();',
+      'parent.iRegExp = /hi/;',
+      'parent.iNaN = NaN;',
+      'parent.iNull = null;',
+      'parent.iBoolean = new Boolean(false);',
+      'parent.iUndefined = undefined;',
+      'parent.iObject = {};',
+      'parent.iError = new Error();',
+      '</script>'
+    ].join('\n')
+  );
+  iDoc.close();
+
+  QUnit.test('isEqual', function(assert) {
+
+    assert.ok(!_.isEqual(iNumber, 101));
+    assert.ok(_.isEqual(iNumber, 100));
+
+    // Objects from another frame.
+    assert.ok(_.isEqual({}, iObject), 'Objects with equivalent members created in different documents are equal');
+
+    // Array from another frame.
+    assert.ok(_.isEqual([1, 2, 3], iArray), 'Arrays with equivalent elements created in different documents are equal');
+  });
+
+  QUnit.test('isEmpty', function(assert) {
+    assert.ok(!_([iNumber]).isEmpty(), '[1] is not empty');
+    assert.ok(!_.isEmpty(iArray), '[] is empty');
+    assert.ok(_.isEmpty(iObject), '{} is empty');
+  });
+
+  QUnit.test('isElement', function(assert) {
+    assert.ok(!_.isElement('div'), 'strings are not dom elements');
+    assert.ok(_.isElement(document.body), 'the body tag is a DOM element');
+    assert.ok(_.isElement(iElement), 'even from another frame');
+  });
+
+  QUnit.test('isArguments', function(assert) {
+    assert.ok(_.isArguments(iArguments), 'even from another frame');
+  });
+
+  QUnit.test('isObject', function(assert) {
+    assert.ok(_.isObject(iElement), 'even from another frame');
+    assert.ok(_.isObject(iFunction), 'even from another frame');
+  });
+
+  QUnit.test('isArray', function(assert) {
+    assert.ok(_.isArray(iArray), 'even from another frame');
+  });
+
+  QUnit.test('isString', function(assert) {
+    assert.ok(_.isString(iString), 'even from another frame');
+  });
+
+  QUnit.test('isNumber', function(assert) {
+    assert.ok(_.isNumber(iNumber), 'even from another frame');
+  });
+
+  QUnit.test('isBoolean', function(assert) {
+    assert.ok(_.isBoolean(iBoolean), 'even from another frame');
+  });
+
+  QUnit.test('isFunction', function(assert) {
+    assert.ok(_.isFunction(iFunction), 'even from another frame');
+  });
+
+  QUnit.test('isDate', function(assert) {
+    assert.ok(_.isDate(iDate), 'even from another frame');
+  });
+
+  QUnit.test('isRegExp', function(assert) {
+    assert.ok(_.isRegExp(iRegExp), 'even from another frame');
+  });
+
+  QUnit.test('isNaN', function(assert) {
+    assert.ok(_.isNaN(iNaN), 'even from another frame');
+  });
+
+  QUnit.test('isNull', function(assert) {
+    assert.ok(_.isNull(iNull), 'even from another frame');
+  });
+
+  QUnit.test('isUndefined', function(assert) {
+    assert.ok(_.isUndefined(iUndefined), 'even from another frame');
+  });
+
+  QUnit.test('isError', function(assert) {
+    assert.ok(_.isError(iError), 'even from another frame');
+  });
+
+  if (typeof ActiveXObject != 'undefined') {
+    QUnit.test('IE host objects', function(assert) {
+      var xml = new ActiveXObject('Msxml2.DOMDocument.3.0');
+      assert.ok(!_.isNumber(xml));
+      assert.ok(!_.isBoolean(xml));
+      assert.ok(!_.isNaN(xml));
+      assert.ok(!_.isFunction(xml));
+      assert.ok(!_.isNull(xml));
+      assert.ok(!_.isUndefined(xml));
+    });
+
+    QUnit.test('#1621 IE 11 compat mode DOM elements are not functions', function(assert) {
+      var fn = function() {};
+      var xml = new ActiveXObject('Msxml2.DOMDocument.3.0');
+      var div = document.createElement('div');
+
+      // JIT the function
+      var count = 200;
+      while (count--) {
+        _.isFunction(fn);
+      }
+
+      assert.equal(_.isFunction(xml), false);
+      assert.equal(_.isFunction(div), false);
+      assert.equal(_.isFunction(fn), true);
+    });
+  }
+
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/functions.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/functions.js
new file mode 100644
index 0000000..f696bd6
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/functions.js
@@ -0,0 +1,728 @@
+(function() {
+  var _ = typeof require == 'function' ? require('..') : window._;
+
+  QUnit.module('Functions');
+  QUnit.config.asyncRetries = 3;
+
+  QUnit.test('bind', function(assert) {
+    var context = {name: 'moe'};
+    var func = function(arg) { return 'name: ' + (this.name || arg); };
+    var bound = _.bind(func, context);
+    assert.equal(bound(), 'name: moe', 'can bind a function to a context');
+
+    bound = _(func).bind(context);
+    assert.equal(bound(), 'name: moe', 'can do OO-style binding');
+
+    bound = _.bind(func, null, 'curly');
+    var result = bound();
+    // Work around a PhantomJS bug when applying a function with null|undefined.
+    assert.ok(result === 'name: curly' || result === 'name: ' + window.name, 'can bind without specifying a context');
+
+    func = function(salutation, name) { return salutation + ': ' + name; };
+    func = _.bind(func, this, 'hello');
+    assert.equal(func('moe'), 'hello: moe', 'the function was partially applied in advance');
+
+    func = _.bind(func, this, 'curly');
+    assert.equal(func(), 'hello: curly', 'the function was completely applied in advance');
+
+    func = function(salutation, firstname, lastname) { return salutation + ': ' + firstname + ' ' + lastname; };
+    func = _.bind(func, this, 'hello', 'moe', 'curly');
+    assert.equal(func(), 'hello: moe curly', 'the function was partially applied in advance and can accept multiple arguments');
+
+    func = function(ctx, message) { assert.equal(this, ctx, message); };
+    _.bind(func, 0, 0, 'can bind a function to `0`')();
+    _.bind(func, '', '', 'can bind a function to an empty string')();
+    _.bind(func, false, false, 'can bind a function to `false`')();
+
+    // These tests are only meaningful when using a browser without a native bind function
+    // To test this with a modern browser, set underscore's nativeBind to undefined
+    var F = function() { return this; };
+    var boundf = _.bind(F, {hello: 'moe curly'});
+    var Boundf = boundf; // make eslint happy.
+    var newBoundf = new Boundf();
+    assert.equal(newBoundf.hello, void 0, 'function should not be bound to the context, to comply with ECMAScript 5');
+    assert.equal(boundf().hello, 'moe curly', "When called without the new operator, it's OK to be bound to the context");
+    assert.ok(newBoundf instanceof F, 'a bound instance is an instance of the original function');
+
+    assert.raises(function() { _.bind('notafunction'); }, TypeError, 'throws an error when binding to a non-function');
+  });
+
+  QUnit.test('partial', function(assert) {
+    var obj = {name: 'moe'};
+    var func = function() { return this.name + ' ' + _.toArray(arguments).join(' '); };
+
+    obj.func = _.partial(func, 'a', 'b');
+    assert.equal(obj.func('c', 'd'), 'moe a b c d', 'can partially apply');
+
+    obj.func = _.partial(func, _, 'b', _, 'd');
+    assert.equal(obj.func('a', 'c'), 'moe a b c d', 'can partially apply with placeholders');
+
+    func = _.partial(function() { return arguments.length; }, _, 'b', _, 'd');
+    assert.equal(func('a', 'c', 'e'), 5, 'accepts more arguments than the number of placeholders');
+    assert.equal(func('a'), 4, 'accepts fewer arguments than the number of placeholders');
+
+    func = _.partial(function() { return typeof arguments[2]; }, _, 'b', _, 'd');
+    assert.equal(func('a'), 'undefined', 'unfilled placeholders are undefined');
+
+    // passes context
+    function MyWidget(name, options) {
+      this.name = name;
+      this.options = options;
+    }
+    MyWidget.prototype.get = function() {
+      return this.name;
+    };
+    var MyWidgetWithCoolOpts = _.partial(MyWidget, _, {a: 1});
+    var widget = new MyWidgetWithCoolOpts('foo');
+    assert.ok(widget instanceof MyWidget, 'Can partially bind a constructor');
+    assert.equal(widget.get(), 'foo', 'keeps prototype');
+    assert.deepEqual(widget.options, {a: 1});
+
+    _.partial.placeholder = obj;
+    func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
+    assert.equal(func('a'), 4, 'allows the placeholder to be swapped out');
+
+    _.partial.placeholder = {};
+    func = _.partial(function() { return arguments.length; }, obj, 'b', obj, 'd');
+    assert.equal(func('a'), 5, 'swapping the placeholder preserves previously bound arguments');
+
+    _.partial.placeholder = _;
+  });
+
+  QUnit.test('bindAll', function(assert) {
+    var curly = {name: 'curly'};
+    var moe = {
+      name: 'moe',
+      getName: function() { return 'name: ' + this.name; },
+      sayHi: function() { return 'hi: ' + this.name; }
+    };
+    curly.getName = moe.getName;
+    _.bindAll(moe, 'getName', 'sayHi');
+    curly.sayHi = moe.sayHi;
+    assert.equal(curly.getName(), 'name: curly', 'unbound function is bound to current object');
+    assert.equal(curly.sayHi(), 'hi: moe', 'bound function is still bound to original object');
+
+    curly = {name: 'curly'};
+    moe = {
+      name: 'moe',
+      getName: function() { return 'name: ' + this.name; },
+      sayHi: function() { return 'hi: ' + this.name; },
+      sayLast: function() { return this.sayHi(_.last(arguments)); }
+    };
+
+    assert.raises(function() { _.bindAll(moe); }, Error, 'throws an error for bindAll with no functions named');
+    assert.raises(function() { _.bindAll(moe, 'sayBye'); }, TypeError, 'throws an error for bindAll if the given key is undefined');
+    assert.raises(function() { _.bindAll(moe, 'name'); }, TypeError, 'throws an error for bindAll if the given key is not a function');
+
+    _.bindAll(moe, 'sayHi', 'sayLast');
+    curly.sayHi = moe.sayHi;
+    assert.equal(curly.sayHi(), 'hi: moe');
+
+    var sayLast = moe.sayLast;
+    assert.equal(sayLast(1, 2, 3, 4, 5, 6, 7, 'Tom'), 'hi: moe', 'createCallback works with any number of arguments');
+
+    _.bindAll(moe, ['getName']);
+    var getName = moe.getName;
+    assert.equal(getName(), 'name: moe', 'flattens arguments into a single list');
+  });
+
+  QUnit.test('memoize', function(assert) {
+    var fib = function(n) {
+      return n < 2 ? n : fib(n - 1) + fib(n - 2);
+    };
+    assert.equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
+    fib = _.memoize(fib); // Redefine `fib` for memoization
+    assert.equal(fib(10), 55, 'a memoized version of fibonacci produces identical results');
+
+    var o = function(str) {
+      return str;
+    };
+    var fastO = _.memoize(o);
+    assert.equal(o('toString'), 'toString', 'checks hasOwnProperty');
+    assert.equal(fastO('toString'), 'toString', 'checks hasOwnProperty');
+
+    // Expose the cache.
+    var upper = _.memoize(function(s) {
+      return s.toUpperCase();
+    });
+    assert.equal(upper('foo'), 'FOO');
+    assert.equal(upper('bar'), 'BAR');
+    assert.deepEqual(upper.cache, {foo: 'FOO', bar: 'BAR'});
+    upper.cache = {foo: 'BAR', bar: 'FOO'};
+    assert.equal(upper('foo'), 'BAR');
+    assert.equal(upper('bar'), 'FOO');
+
+    var hashed = _.memoize(function(key) {
+      //https://github.com/jashkenas/underscore/pull/1679#discussion_r13736209
+      assert.ok(/[a-z]+/.test(key), 'hasher doesn\'t change keys');
+      return key;
+    }, function(key) {
+      return key.toUpperCase();
+    });
+    hashed('yep');
+    assert.deepEqual(hashed.cache, {YEP: 'yep'}, 'takes a hasher');
+
+    // Test that the hash function can be used to swizzle the key.
+    var objCacher = _.memoize(function(value, key) {
+      return {key: key, value: value};
+    }, function(value, key) {
+      return key;
+    });
+    var myObj = objCacher('a', 'alpha');
+    var myObjAlias = objCacher('b', 'alpha');
+    assert.notStrictEqual(myObj, void 0, 'object is created if second argument used as key');
+    assert.strictEqual(myObj, myObjAlias, 'object is cached if second argument used as key');
+    assert.strictEqual(myObj.value, 'a', 'object is not modified if second argument used as key');
+  });
+
+  QUnit.test('delay', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var delayed = false;
+    _.delay(function(){ delayed = true; }, 100);
+    setTimeout(function(){ assert.ok(!delayed, "didn't delay the function quite yet"); }, 50);
+    setTimeout(function(){ assert.ok(delayed, 'delayed the function'); done(); }, 150);
+  });
+
+  QUnit.test('defer', function(assert) {
+    assert.expect(1);
+    var done = assert.async();
+    var deferred = false;
+    _.defer(function(bool){ deferred = bool; }, true);
+    _.delay(function(){ assert.ok(deferred, 'deferred the function'); done(); }, 50);
+  });
+
+  QUnit.test('throttle', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 32);
+    throttledIncr(); throttledIncr();
+
+    assert.equal(counter, 1, 'incr was called immediately');
+    _.delay(function(){ assert.equal(counter, 2, 'incr was throttled'); done(); }, 64);
+  });
+
+  QUnit.test('throttle arguments', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var value = 0;
+    var update = function(val){ value = val; };
+    var throttledUpdate = _.throttle(update, 32);
+    throttledUpdate(1); throttledUpdate(2);
+    _.delay(function(){ throttledUpdate(3); }, 64);
+    assert.equal(value, 1, 'updated to latest value');
+    _.delay(function(){ assert.equal(value, 3, 'updated to latest value'); done(); }, 96);
+  });
+
+  QUnit.test('throttle once', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ return ++counter; };
+    var throttledIncr = _.throttle(incr, 32);
+    var result = throttledIncr();
+    _.delay(function(){
+      assert.equal(result, 1, 'throttled functions return their value');
+      assert.equal(counter, 1, 'incr was called once'); done();
+    }, 64);
+  });
+
+  QUnit.test('throttle twice', function(assert) {
+    assert.expect(1);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 32);
+    throttledIncr(); throttledIncr();
+    _.delay(function(){ assert.equal(counter, 2, 'incr was called twice'); done(); }, 64);
+  });
+
+  QUnit.test('more throttling', function(assert) {
+    assert.expect(3);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 30);
+    throttledIncr(); throttledIncr();
+    assert.equal(counter, 1);
+    _.delay(function(){
+      assert.equal(counter, 2);
+      throttledIncr();
+      assert.equal(counter, 3);
+      done();
+    }, 85);
+  });
+
+  QUnit.test('throttle repeatedly with results', function(assert) {
+    assert.expect(6);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ return ++counter; };
+    var throttledIncr = _.throttle(incr, 100);
+    var results = [];
+    var saveResult = function() { results.push(throttledIncr()); };
+    saveResult(); saveResult();
+    _.delay(saveResult, 50);
+    _.delay(saveResult, 150);
+    _.delay(saveResult, 160);
+    _.delay(saveResult, 230);
+    _.delay(function() {
+      assert.equal(results[0], 1, 'incr was called once');
+      assert.equal(results[1], 1, 'incr was throttled');
+      assert.equal(results[2], 1, 'incr was throttled');
+      assert.equal(results[3], 2, 'incr was called twice');
+      assert.equal(results[4], 2, 'incr was throttled');
+      assert.equal(results[5], 3, 'incr was called trailing');
+      done();
+    }, 300);
+  });
+
+  QUnit.test('throttle triggers trailing call when invoked repeatedly', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var limit = 48;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 32);
+
+    var stamp = new Date;
+    while (new Date - stamp < limit) {
+      throttledIncr();
+    }
+    var lastCount = counter;
+    assert.ok(counter > 1);
+
+    _.delay(function() {
+      assert.ok(counter > lastCount);
+      done();
+    }, 96);
+  });
+
+  QUnit.test('throttle does not trigger leading call when leading is set to false', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 60, {leading: false});
+
+    throttledIncr(); throttledIncr();
+    assert.equal(counter, 0);
+
+    _.delay(function() {
+      assert.equal(counter, 1);
+      done();
+    }, 96);
+  });
+
+  QUnit.test('more throttle does not trigger leading call when leading is set to false', function(assert) {
+    assert.expect(3);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 100, {leading: false});
+
+    throttledIncr();
+    _.delay(throttledIncr, 50);
+    _.delay(throttledIncr, 60);
+    _.delay(throttledIncr, 200);
+    assert.equal(counter, 0);
+
+    _.delay(function() {
+      assert.equal(counter, 1);
+    }, 250);
+
+    _.delay(function() {
+      assert.equal(counter, 2);
+      done();
+    }, 350);
+  });
+
+  QUnit.test('one more throttle with leading: false test', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 100, {leading: false});
+
+    var time = new Date;
+    while (new Date - time < 350) throttledIncr();
+    assert.ok(counter <= 3);
+
+    _.delay(function() {
+      assert.ok(counter <= 4);
+      done();
+    }, 200);
+  });
+
+  QUnit.test('throttle does not trigger trailing call when trailing is set to false', function(assert) {
+    assert.expect(4);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 60, {trailing: false});
+
+    throttledIncr(); throttledIncr(); throttledIncr();
+    assert.equal(counter, 1);
+
+    _.delay(function() {
+      assert.equal(counter, 1);
+
+      throttledIncr(); throttledIncr();
+      assert.equal(counter, 2);
+
+      _.delay(function() {
+        assert.equal(counter, 2);
+        done();
+      }, 96);
+    }, 96);
+  });
+
+  QUnit.test('throttle continues to function after system time is set backwards', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 100);
+    var origNowFunc = _.now;
+
+    throttledIncr();
+    assert.equal(counter, 1);
+    _.now = function() {
+      return new Date(2013, 0, 1, 1, 1, 1);
+    };
+
+    _.delay(function() {
+      throttledIncr();
+      assert.equal(counter, 2);
+      done();
+      _.now = origNowFunc;
+    }, 200);
+  });
+
+  QUnit.test('throttle re-entrant', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var sequence = [
+      ['b1', 'b2'],
+      ['c1', 'c2']
+    ];
+    var value = '';
+    var throttledAppend;
+    var append = function(arg){
+      value += this + arg;
+      var args = sequence.pop();
+      if (args) {
+        throttledAppend.call(args[0], args[1]);
+      }
+    };
+    throttledAppend = _.throttle(append, 32);
+    throttledAppend.call('a1', 'a2');
+    assert.equal(value, 'a1a2');
+    _.delay(function(){
+      assert.equal(value, 'a1a2c1c2b1b2', 'append was throttled successfully');
+      done();
+    }, 100);
+  });
+
+  QUnit.test('throttle cancel', function(assert) {
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 32);
+    throttledIncr();
+    throttledIncr.cancel();
+    throttledIncr();
+    throttledIncr();
+
+    assert.equal(counter, 2, 'incr was called immediately');
+    _.delay(function(){ assert.equal(counter, 3, 'incr was throttled'); done(); }, 64);
+  });
+
+  QUnit.test('throttle cancel with leading: false', function(assert) {
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var throttledIncr = _.throttle(incr, 32, {leading: false});
+    throttledIncr();
+    throttledIncr.cancel();
+
+    assert.equal(counter, 0, 'incr was throttled');
+    _.delay(function(){ assert.equal(counter, 0, 'incr was throttled'); done(); }, 64);
+  });
+
+  QUnit.test('debounce', function(assert) {
+    assert.expect(1);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var debouncedIncr = _.debounce(incr, 32);
+    debouncedIncr(); debouncedIncr();
+    _.delay(debouncedIncr, 16);
+    _.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 96);
+  });
+
+  QUnit.test('debounce cancel', function(assert) {
+    assert.expect(1);
+    var done = assert.async();
+    var counter = 0;
+    var incr = function(){ counter++; };
+    var debouncedIncr = _.debounce(incr, 32);
+    debouncedIncr();
+    debouncedIncr.cancel();
+    _.delay(function(){ assert.equal(counter, 0, 'incr was not called'); done(); }, 96);
+  });
+
+  QUnit.test('debounce asap', function(assert) {
+    assert.expect(6);
+    var done = assert.async();
+    var a, b, c;
+    var counter = 0;
+    var incr = function(){ return ++counter; };
+    var debouncedIncr = _.debounce(incr, 64, true);
+    a = debouncedIncr();
+    b = debouncedIncr();
+    assert.equal(a, 1);
+    assert.equal(b, 1);
+    assert.equal(counter, 1, 'incr was called immediately');
+    _.delay(debouncedIncr, 16);
+    _.delay(debouncedIncr, 32);
+    _.delay(debouncedIncr, 48);
+    _.delay(function(){
+      assert.equal(counter, 1, 'incr was debounced');
+      c = debouncedIncr();
+      assert.equal(c, 2);
+      assert.equal(counter, 2, 'incr was called again');
+      done();
+    }, 128);
+  });
+
+  QUnit.test('debounce asap cancel', function(assert) {
+    assert.expect(4);
+    var done = assert.async();
+    var a, b;
+    var counter = 0;
+    var incr = function(){ return ++counter; };
+    var debouncedIncr = _.debounce(incr, 64, true);
+    a = debouncedIncr();
+    debouncedIncr.cancel();
+    b = debouncedIncr();
+    assert.equal(a, 1);
+    assert.equal(b, 2);
+    assert.equal(counter, 2, 'incr was called immediately');
+    _.delay(debouncedIncr, 16);
+    _.delay(debouncedIncr, 32);
+    _.delay(debouncedIncr, 48);
+    _.delay(function(){ assert.equal(counter, 2, 'incr was debounced'); done(); }, 128);
+  });
+
+  QUnit.test('debounce asap recursively', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var debouncedIncr = _.debounce(function(){
+      counter++;
+      if (counter < 10) debouncedIncr();
+    }, 32, true);
+    debouncedIncr();
+    assert.equal(counter, 1, 'incr was called immediately');
+    _.delay(function(){ assert.equal(counter, 1, 'incr was debounced'); done(); }, 96);
+  });
+
+  QUnit.test('debounce after system time is set backwards', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var counter = 0;
+    var origNowFunc = _.now;
+    var debouncedIncr = _.debounce(function(){
+      counter++;
+    }, 100, true);
+
+    debouncedIncr();
+    assert.equal(counter, 1, 'incr was called immediately');
+
+    _.now = function() {
+      return new Date(2013, 0, 1, 1, 1, 1);
+    };
+
+    _.delay(function() {
+      debouncedIncr();
+      assert.equal(counter, 2, 'incr was debounced successfully');
+      done();
+      _.now = origNowFunc;
+    }, 200);
+  });
+
+  QUnit.test('debounce re-entrant', function(assert) {
+    assert.expect(2);
+    var done = assert.async();
+    var sequence = [
+      ['b1', 'b2']
+    ];
+    var value = '';
+    var debouncedAppend;
+    var append = function(arg){
+      value += this + arg;
+      var args = sequence.pop();
+      if (args) {
+        debouncedAppend.call(args[0], args[1]);
+      }
+    };
+    debouncedAppend = _.debounce(append, 32);
+    debouncedAppend.call('a1', 'a2');
+    assert.equal(value, '');
+    _.delay(function(){
+      assert.equal(value, 'a1a2b1b2', 'append was debounced successfully');
+      done();
+    }, 100);
+  });
+
+  QUnit.test('once', function(assert) {
+    var num = 0;
+    var increment = _.once(function(){ return ++num; });
+    increment();
+    increment();
+    assert.equal(num, 1);
+
+    assert.equal(increment(), 1, 'stores a memo to the last value');
+  });
+
+  QUnit.test('Recursive onced function.', function(assert) {
+    assert.expect(1);
+    var f = _.once(function(){
+      assert.ok(true);
+      f();
+    });
+    f();
+  });
+
+  QUnit.test('wrap', function(assert) {
+    var greet = function(name){ return 'hi: ' + name; };
+    var backwards = _.wrap(greet, function(func, name){ return func(name) + ' ' + name.split('').reverse().join(''); });
+    assert.equal(backwards('moe'), 'hi: moe eom', 'wrapped the salutation function');
+
+    var inner = function(){ return 'Hello '; };
+    var obj = {name: 'Moe'};
+    obj.hi = _.wrap(inner, function(fn){ return fn() + this.name; });
+    assert.equal(obj.hi(), 'Hello Moe');
+
+    var noop = function(){};
+    var wrapped = _.wrap(noop, function(){ return Array.prototype.slice.call(arguments, 0); });
+    var ret = wrapped(['whats', 'your'], 'vector', 'victor');
+    assert.deepEqual(ret, [noop, ['whats', 'your'], 'vector', 'victor']);
+  });
+
+  QUnit.test('negate', function(assert) {
+    var isOdd = function(n){ return n & 1; };
+    assert.equal(_.negate(isOdd)(2), true, 'should return the complement of the given function');
+    assert.equal(_.negate(isOdd)(3), false, 'should return the complement of the given function');
+  });
+
+  QUnit.test('compose', function(assert) {
+    var greet = function(name){ return 'hi: ' + name; };
+    var exclaim = function(sentence){ return sentence + '!'; };
+    var composed = _.compose(exclaim, greet);
+    assert.equal(composed('moe'), 'hi: moe!', 'can compose a function that takes another');
+
+    composed = _.compose(greet, exclaim);
+    assert.equal(composed('moe'), 'hi: moe!', 'in this case, the functions are also commutative');
+
+    // f(g(h(x, y, z)))
+    function h(x, y, z) {
+      assert.equal(arguments.length, 3, 'First function called with multiple args');
+      return z * y;
+    }
+    function g(x) {
+      assert.equal(arguments.length, 1, 'Composed function is called with 1 argument');
+      return x;
+    }
+    function f(x) {
+      assert.equal(arguments.length, 1, 'Composed function is called with 1 argument');
+      return x * 2;
+    }
+    composed = _.compose(f, g, h);
+    assert.equal(composed(1, 2, 3), 12);
+  });
+
+  QUnit.test('after', function(assert) {
+    var testAfter = function(afterAmount, timesCalled) {
+      var afterCalled = 0;
+      var after = _.after(afterAmount, function() {
+        afterCalled++;
+      });
+      while (timesCalled--) after();
+      return afterCalled;
+    };
+
+    assert.equal(testAfter(5, 5), 1, 'after(N) should fire after being called N times');
+    assert.equal(testAfter(5, 4), 0, 'after(N) should not fire unless called N times');
+    assert.equal(testAfter(0, 0), 0, 'after(0) should not fire immediately');
+    assert.equal(testAfter(0, 1), 1, 'after(0) should fire when first invoked');
+  });
+
+  QUnit.test('before', function(assert) {
+    var testBefore = function(beforeAmount, timesCalled) {
+      var beforeCalled = 0;
+      var before = _.before(beforeAmount, function() { beforeCalled++; });
+      while (timesCalled--) before();
+      return beforeCalled;
+    };
+
+    assert.equal(testBefore(5, 5), 4, 'before(N) should not fire after being called N times');
+    assert.equal(testBefore(5, 4), 4, 'before(N) should fire before being called N times');
+    assert.equal(testBefore(0, 0), 0, 'before(0) should not fire immediately');
+    assert.equal(testBefore(0, 1), 0, 'before(0) should not fire when first invoked');
+
+    var context = {num: 0};
+    var increment = _.before(3, function(){ return ++this.num; });
+    _.times(10, increment, context);
+    assert.equal(increment(), 2, 'stores a memo to the last value');
+    assert.equal(context.num, 2, 'provides context');
+  });
+
+  QUnit.test('iteratee', function(assert) {
+    var identity = _.iteratee();
+    assert.equal(identity, _.identity, '_.iteratee is exposed as an external function.');
+
+    function fn() {
+      return arguments;
+    }
+    _.each([_.iteratee(fn), _.iteratee(fn, {})], function(cb) {
+      assert.equal(cb().length, 0);
+      assert.deepEqual(_.toArray(cb(1, 2, 3)), _.range(1, 4));
+      assert.deepEqual(_.toArray(cb(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)), _.range(1, 11));
+    });
+
+  });
+
+  QUnit.test('restArgs', function(assert) {
+    assert.expect(10);
+    _.restArgs(function(a, args) {
+      assert.strictEqual(a, 1);
+      assert.deepEqual(args, [2, 3], 'collects rest arguments into an array');
+    })(1, 2, 3);
+
+    _.restArgs(function(a, args) {
+      assert.strictEqual(a, void 0);
+      assert.deepEqual(args, [], 'passes empty array if there are not enough arguments');
+    })();
+
+    _.restArgs(function(a, b, c, args) {
+      assert.strictEqual(arguments.length, 4);
+      assert.deepEqual(args, [4, 5], 'works on functions with many named parameters');
+    })(1, 2, 3, 4, 5);
+
+    var obj = {};
+    _.restArgs(function() {
+      assert.strictEqual(this, obj, 'invokes function with this context');
+    }).call(obj);
+
+    _.restArgs(function(array, iteratee, context) {
+      assert.deepEqual(array, [1, 2, 3, 4], 'startIndex can be used manually specify index of rest parameter');
+      assert.strictEqual(iteratee, void 0);
+      assert.strictEqual(context, void 0);
+    }, 0)(1, 2, 3, 4);
+  });
+
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/objects.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/objects.js
new file mode 100644
index 0000000..fa1d9e3
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/objects.js
@@ -0,0 +1,1102 @@
+(function() {
+  var _ = typeof require == 'function' ? require('..') : window._;
+
+  QUnit.module('Objects');
+
+  var testElement = typeof document === 'object' ? document.createElement('div') : void 0;
+
+  QUnit.test('keys', function(assert) {
+    assert.deepEqual(_.keys({one: 1, two: 2}), ['one', 'two'], 'can extract the keys from an object');
+    // the test above is not safe because it relies on for-in enumeration order
+    var a = []; a[1] = 0;
+    assert.deepEqual(_.keys(a), ['1'], 'is not fooled by sparse arrays; see issue #95');
+    assert.deepEqual(_.keys(null), []);
+    assert.deepEqual(_.keys(void 0), []);
+    assert.deepEqual(_.keys(1), []);
+    assert.deepEqual(_.keys('a'), []);
+    assert.deepEqual(_.keys(true), []);
+
+    // keys that may be missed if the implementation isn't careful
+    var trouble = {
+      constructor: Object,
+      valueOf: _.noop,
+      hasOwnProperty: null,
+      toString: 5,
+      toLocaleString: void 0,
+      propertyIsEnumerable: /a/,
+      isPrototypeOf: this,
+      __defineGetter__: Boolean,
+      __defineSetter__: {},
+      __lookupSetter__: false,
+      __lookupGetter__: []
+    };
+    var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable',
+                  'isPrototypeOf', '__defineGetter__', '__defineSetter__', '__lookupSetter__', '__lookupGetter__'].sort();
+    assert.deepEqual(_.keys(trouble).sort(), troubleKeys, 'matches non-enumerable properties');
+  });
+
+  QUnit.test('allKeys', function(assert) {
+    assert.deepEqual(_.allKeys({one: 1, two: 2}), ['one', 'two'], 'can extract the allKeys from an object');
+    // the test above is not safe because it relies on for-in enumeration order
+    var a = []; a[1] = 0;
+    assert.deepEqual(_.allKeys(a), ['1'], 'is not fooled by sparse arrays; see issue #95');
+
+    a.a = a;
+    assert.deepEqual(_.allKeys(a), ['1', 'a'], 'is not fooled by sparse arrays with additional properties');
+
+    _.each([null, void 0, 1, 'a', true, NaN, {}, [], new Number(5), new Date(0)], function(val) {
+      assert.deepEqual(_.allKeys(val), []);
+    });
+
+    // allKeys that may be missed if the implementation isn't careful
+    var trouble = {
+      constructor: Object,
+      valueOf: _.noop,
+      hasOwnProperty: null,
+      toString: 5,
+      toLocaleString: void 0,
+      propertyIsEnumerable: /a/,
+      isPrototypeOf: this
+    };
+    var troubleKeys = ['constructor', 'valueOf', 'hasOwnProperty', 'toString', 'toLocaleString', 'propertyIsEnumerable',
+                  'isPrototypeOf'].sort();
+    assert.deepEqual(_.allKeys(trouble).sort(), troubleKeys, 'matches non-enumerable properties');
+
+    function A() {}
+    A.prototype.foo = 'foo';
+    var b = new A();
+    b.bar = 'bar';
+    assert.deepEqual(_.allKeys(b).sort(), ['bar', 'foo'], 'should include inherited keys');
+
+    function y() {}
+    y.x = 'z';
+    assert.deepEqual(_.allKeys(y), ['x'], 'should get keys from constructor');
+  });
+
+  QUnit.test('values', function(assert) {
+    assert.deepEqual(_.values({one: 1, two: 2}), [1, 2], 'can extract the values from an object');
+    assert.deepEqual(_.values({one: 1, two: 2, length: 3}), [1, 2, 3], '... even when one of them is "length"');
+  });
+
+  QUnit.test('pairs', function(assert) {
+    assert.deepEqual(_.pairs({one: 1, two: 2}), [['one', 1], ['two', 2]], 'can convert an object into pairs');
+    assert.deepEqual(_.pairs({one: 1, two: 2, length: 3}), [['one', 1], ['two', 2], ['length', 3]], '... even when one of them is "length"');
+  });
+
+  QUnit.test('invert', function(assert) {
+    var obj = {first: 'Moe', second: 'Larry', third: 'Curly'};
+    assert.deepEqual(_.keys(_.invert(obj)), ['Moe', 'Larry', 'Curly'], 'can invert an object');
+    assert.deepEqual(_.invert(_.invert(obj)), obj, 'two inverts gets you back where you started');
+
+    obj = {length: 3};
+    assert.equal(_.invert(obj)['3'], 'length', 'can invert an object with "length"');
+  });
+
+  QUnit.test('functions', function(assert) {
+    var obj = {a: 'dash', b: _.map, c: /yo/, d: _.reduce};
+    assert.deepEqual(['b', 'd'], _.functions(obj), 'can grab the function names of any passed-in object');
+
+    var Animal = function(){};
+    Animal.prototype.run = function(){};
+    assert.deepEqual(_.functions(new Animal), ['run'], 'also looks up functions on the prototype');
+  });
+
+  QUnit.test('methods', function(assert) {
+    assert.strictEqual(_.methods, _.functions, 'is an alias for functions');
+  });
+
+  QUnit.test('extend', function(assert) {
+    var result;
+    assert.equal(_.extend({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another');
+    assert.equal(_.extend({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination');
+    assert.equal(_.extend({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overriden");
+    result = _.extend({x: 'x'}, {a: 'a'}, {b: 'b'});
+    assert.deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can extend from multiple source objects');
+    result = _.extend({x: 'x'}, {a: 'a', x: 2}, {a: 'b'});
+    assert.deepEqual(result, {x: 2, a: 'b'}, 'extending from multiple source objects last property trumps');
+    result = _.extend({}, {a: void 0, b: null});
+    assert.deepEqual(_.keys(result), ['a', 'b'], 'extend copies undefined values');
+
+    var F = function() {};
+    F.prototype = {a: 'b'};
+    var subObj = new F();
+    subObj.c = 'd';
+    assert.deepEqual(_.extend({}, subObj), {a: 'b', c: 'd'}, 'extend copies all properties from source');
+    _.extend(subObj, {});
+    assert.ok(!subObj.hasOwnProperty('a'), "extend does not convert destination object's 'in' properties to 'own' properties");
+
+    try {
+      result = {};
+      _.extend(result, null, void 0, {a: 1});
+    } catch (e) { /* ignored */ }
+
+    assert.equal(result.a, 1, 'should not error on `null` or `undefined` sources');
+
+    assert.strictEqual(_.extend(null, {a: 1}), null, 'extending null results in null');
+    assert.strictEqual(_.extend(void 0, {a: 1}), void 0, 'extending undefined results in undefined');
+  });
+
+  QUnit.test('extendOwn', function(assert) {
+    var result;
+    assert.equal(_.extendOwn({}, {a: 'b'}).a, 'b', 'can extend an object with the attributes of another');
+    assert.equal(_.extendOwn({a: 'x'}, {a: 'b'}).a, 'b', 'properties in source override destination');
+    assert.equal(_.extendOwn({x: 'x'}, {a: 'b'}).x, 'x', "properties not in source don't get overriden");
+    result = _.extendOwn({x: 'x'}, {a: 'a'}, {b: 'b'});
+    assert.deepEqual(result, {x: 'x', a: 'a', b: 'b'}, 'can extend from multiple source objects');
+    result = _.extendOwn({x: 'x'}, {a: 'a', x: 2}, {a: 'b'});
+    assert.deepEqual(result, {x: 2, a: 'b'}, 'extending from multiple source objects last property trumps');
+    assert.deepEqual(_.extendOwn({}, {a: void 0, b: null}), {a: void 0, b: null}, 'copies undefined values');
+
+    var F = function() {};
+    F.prototype = {a: 'b'};
+    var subObj = new F();
+    subObj.c = 'd';
+    assert.deepEqual(_.extendOwn({}, subObj), {c: 'd'}, 'copies own properties from source');
+
+    result = {};
+    assert.deepEqual(_.extendOwn(result, null, void 0, {a: 1}), {a: 1}, 'should not error on `null` or `undefined` sources');
+
+    _.each(['a', 5, null, false], function(val) {
+      assert.strictEqual(_.extendOwn(val, {a: 1}), val, 'extending non-objects results in returning the non-object value');
+    });
+
+    assert.strictEqual(_.extendOwn(void 0, {a: 1}), void 0, 'extending undefined results in undefined');
+
+    result = _.extendOwn({a: 1, 0: 2, 1: '5', length: 6}, {0: 1, 1: 2, length: 2});
+    assert.deepEqual(result, {a: 1, 0: 1, 1: 2, length: 2}, 'should treat array-like objects like normal objects');
+  });
+
+  QUnit.test('assign', function(assert) {
+    assert.strictEqual(_.assign, _.extendOwn, 'is an alias for extendOwn');
+  });
+
+  QUnit.test('pick', function(assert) {
+    var result;
+    result = _.pick({a: 1, b: 2, c: 3}, 'a', 'c');
+    assert.deepEqual(result, {a: 1, c: 3}, 'can restrict properties to those named');
+    result = _.pick({a: 1, b: 2, c: 3}, ['b', 'c']);
+    assert.deepEqual(result, {b: 2, c: 3}, 'can restrict properties to those named in an array');
+    result = _.pick({a: 1, b: 2, c: 3}, ['a'], 'b');
+    assert.deepEqual(result, {a: 1, b: 2}, 'can restrict properties to those named in mixed args');
+    result = _.pick(['a', 'b'], 1);
+    assert.deepEqual(result, {1: 'b'}, 'can pick numeric properties');
+
+    _.each([null, void 0], function(val) {
+      assert.deepEqual(_.pick(val, 'hasOwnProperty'), {}, 'Called with null/undefined');
+      assert.deepEqual(_.pick(val, _.constant(true)), {});
+    });
+    assert.deepEqual(_.pick(5, 'toString', 'b'), {toString: Number.prototype.toString}, 'can iterate primitives');
+
+    var data = {a: 1, b: 2, c: 3};
+    var callback = function(value, key, object) {
+      assert.strictEqual(key, {1: 'a', 2: 'b', 3: 'c'}[value]);
+      assert.strictEqual(object, data);
+      return value !== this.value;
+    };
+    result = _.pick(data, callback, {value: 2});
+    assert.deepEqual(result, {a: 1, c: 3}, 'can accept a predicate and context');
+
+    var Obj = function(){};
+    Obj.prototype = {a: 1, b: 2, c: 3};
+    var instance = new Obj();
+    assert.deepEqual(_.pick(instance, 'a', 'c'), {a: 1, c: 3}, 'include prototype props');
+
+    assert.deepEqual(_.pick(data, function(val, key) {
+      return this[key] === 3 && this === instance;
+    }, instance), {c: 3}, 'function is given context');
+
+    assert.ok(!_.has(_.pick({}, 'foo'), 'foo'), 'does not set own property if property not in object');
+    _.pick(data, function(value, key, obj) {
+      assert.equal(obj, data, 'passes same object as third parameter of iteratee');
+    });
+  });
+
+  QUnit.test('omit', function(assert) {
+    var result;
+    result = _.omit({a: 1, b: 2, c: 3}, 'b');
+    assert.deepEqual(result, {a: 1, c: 3}, 'can omit a single named property');
+    result = _.omit({a: 1, b: 2, c: 3}, 'a', 'c');
+    assert.deepEqual(result, {b: 2}, 'can omit several named properties');
+    result = _.omit({a: 1, b: 2, c: 3}, ['b', 'c']);
+    assert.deepEqual(result, {a: 1}, 'can omit properties named in an array');
+    result = _.omit(['a', 'b'], 0);
+    assert.deepEqual(result, {1: 'b'}, 'can omit numeric properties');
+
+    assert.deepEqual(_.omit(null, 'a', 'b'), {}, 'non objects return empty object');
+    assert.deepEqual(_.omit(void 0, 'toString'), {}, 'null/undefined return empty object');
+    assert.deepEqual(_.omit(5, 'toString', 'b'), {}, 'returns empty object for primitives');
+
+    var data = {a: 1, b: 2, c: 3};
+    var callback = function(value, key, object) {
+      assert.strictEqual(key, {1: 'a', 2: 'b', 3: 'c'}[value]);
+      assert.strictEqual(object, data);
+      return value !== this.value;
+    };
+    result = _.omit(data, callback, {value: 2});
+    assert.deepEqual(result, {b: 2}, 'can accept a predicate');
+
+    var Obj = function(){};
+    Obj.prototype = {a: 1, b: 2, c: 3};
+    var instance = new Obj();
+    assert.deepEqual(_.omit(instance, 'b'), {a: 1, c: 3}, 'include prototype props');
+
+    assert.deepEqual(_.omit(data, function(val, key) {
+      return this[key] === 3 && this === instance;
+    }, instance), {a: 1, b: 2}, 'function is given context');
+  });
+
+  QUnit.test('defaults', function(assert) {
+    var options = {zero: 0, one: 1, empty: '', nan: NaN, nothing: null};
+
+    _.defaults(options, {zero: 1, one: 10, twenty: 20, nothing: 'str'});
+    assert.equal(options.zero, 0, 'value exists');
+    assert.equal(options.one, 1, 'value exists');
+    assert.equal(options.twenty, 20, 'default applied');
+    assert.equal(options.nothing, null, "null isn't overridden");
+
+    _.defaults(options, {empty: 'full'}, {nan: 'nan'}, {word: 'word'}, {word: 'dog'});
+    assert.equal(options.empty, '', 'value exists');
+    assert.ok(_.isNaN(options.nan), "NaN isn't overridden");
+    assert.equal(options.word, 'word', 'new value is added, first one wins');
+
+    try {
+      options = {};
+      _.defaults(options, null, void 0, {a: 1});
+    } catch (e) { /* ignored */ }
+
+    assert.equal(options.a, 1, 'should not error on `null` or `undefined` sources');
+
+    assert.deepEqual(_.defaults(null, {a: 1}), {a: 1}, 'defaults skips nulls');
+    assert.deepEqual(_.defaults(void 0, {a: 1}), {a: 1}, 'defaults skips undefined');
+  });
+
+  QUnit.test('clone', function(assert) {
+    var moe = {name: 'moe', lucky: [13, 27, 34]};
+    var clone = _.clone(moe);
+    assert.equal(clone.name, 'moe', 'the clone as the attributes of the original');
+
+    clone.name = 'curly';
+    assert.ok(clone.name === 'curly' && moe.name === 'moe', 'clones can change shallow attributes without affecting the original');
+
+    clone.lucky.push(101);
+    assert.equal(_.last(moe.lucky), 101, 'changes to deep attributes are shared with the original');
+
+    assert.equal(_.clone(void 0), void 0, 'non objects should not be changed by clone');
+    assert.equal(_.clone(1), 1, 'non objects should not be changed by clone');
+    assert.equal(_.clone(null), null, 'non objects should not be changed by clone');
+  });
+
+  QUnit.test('create', function(assert) {
+    var Parent = function() {};
+    Parent.prototype = {foo: function() {}, bar: 2};
+
+    _.each(['foo', null, void 0, 1], function(val) {
+      assert.deepEqual(_.create(val), {}, 'should return empty object when a non-object is provided');
+    });
+
+    assert.ok(_.create([]) instanceof Array, 'should return new instance of array when array is provided');
+
+    var Child = function() {};
+    Child.prototype = _.create(Parent.prototype);
+    assert.ok(new Child instanceof Parent, 'object should inherit prototype');
+
+    var func = function() {};
+    Child.prototype = _.create(Parent.prototype, {func: func});
+    assert.strictEqual(Child.prototype.func, func, 'properties should be added to object');
+
+    Child.prototype = _.create(Parent.prototype, {constructor: Child});
+    assert.strictEqual(Child.prototype.constructor, Child);
+
+    Child.prototype.foo = 'foo';
+    var created = _.create(Child.prototype, new Child);
+    assert.ok(!created.hasOwnProperty('foo'), 'should only add own properties');
+  });
+
+  QUnit.test('isEqual', function(assert) {
+    function First() {
+      this.value = 1;
+    }
+    First.prototype.value = 1;
+    function Second() {
+      this.value = 1;
+    }
+    Second.prototype.value = 2;
+
+    // Basic equality and identity comparisons.
+    assert.ok(_.isEqual(null, null), '`null` is equal to `null`');
+    assert.ok(_.isEqual(), '`undefined` is equal to `undefined`');
+
+    assert.ok(!_.isEqual(0, -0), '`0` is not equal to `-0`');
+    assert.ok(!_.isEqual(-0, 0), 'Commutative equality is implemented for `0` and `-0`');
+    assert.ok(!_.isEqual(null, void 0), '`null` is not equal to `undefined`');
+    assert.ok(!_.isEqual(void 0, null), 'Commutative equality is implemented for `null` and `undefined`');
+
+    // String object and primitive comparisons.
+    assert.ok(_.isEqual('Curly', 'Curly'), 'Identical string primitives are equal');
+    assert.ok(_.isEqual(new String('Curly'), new String('Curly')), 'String objects with identical primitive values are equal');
+    assert.ok(_.isEqual(new String('Curly'), 'Curly'), 'String primitives and their corresponding object wrappers are equal');
+    assert.ok(_.isEqual('Curly', new String('Curly')), 'Commutative equality is implemented for string objects and primitives');
+
+    assert.ok(!_.isEqual('Curly', 'Larry'), 'String primitives with different values are not equal');
+    assert.ok(!_.isEqual(new String('Curly'), new String('Larry')), 'String objects with different primitive values are not equal');
+    assert.ok(!_.isEqual(new String('Curly'), {toString: function(){ return 'Curly'; }}), 'String objects and objects with a custom `toString` method are not equal');
+
+    // Number object and primitive comparisons.
+    assert.ok(_.isEqual(75, 75), 'Identical number primitives are equal');
+    assert.ok(_.isEqual(new Number(75), new Number(75)), 'Number objects with identical primitive values are equal');
+    assert.ok(_.isEqual(75, new Number(75)), 'Number primitives and their corresponding object wrappers are equal');
+    assert.ok(_.isEqual(new Number(75), 75), 'Commutative equality is implemented for number objects and primitives');
+    assert.ok(!_.isEqual(new Number(0), -0), '`new Number(0)` and `-0` are not equal');
+    assert.ok(!_.isEqual(0, new Number(-0)), 'Commutative equality is implemented for `new Number(0)` and `-0`');
+
+    assert.ok(!_.isEqual(new Number(75), new Number(63)), 'Number objects with different primitive values are not equal');
+    assert.ok(!_.isEqual(new Number(63), {valueOf: function(){ return 63; }}), 'Number objects and objects with a `valueOf` method are not equal');
+
+    // Comparisons involving `NaN`.
+    assert.ok(_.isEqual(NaN, NaN), '`NaN` is equal to `NaN`');
+    assert.ok(_.isEqual(new Number(NaN), NaN), 'Object(`NaN`) is equal to `NaN`');
+    assert.ok(!_.isEqual(61, NaN), 'A number primitive is not equal to `NaN`');
+    assert.ok(!_.isEqual(new Number(79), NaN), 'A number object is not equal to `NaN`');
+    assert.ok(!_.isEqual(Infinity, NaN), '`Infinity` is not equal to `NaN`');
+
+    // Boolean object and primitive comparisons.
+    assert.ok(_.isEqual(true, true), 'Identical boolean primitives are equal');
+    assert.ok(_.isEqual(new Boolean, new Boolean), 'Boolean objects with identical primitive values are equal');
+    assert.ok(_.isEqual(true, new Boolean(true)), 'Boolean primitives and their corresponding object wrappers are equal');
+    assert.ok(_.isEqual(new Boolean(true), true), 'Commutative equality is implemented for booleans');
+    assert.ok(!_.isEqual(new Boolean(true), new Boolean), 'Boolean objects with different primitive values are not equal');
+
+    // Common type coercions.
+    assert.ok(!_.isEqual(new Boolean(false), true), '`new Boolean(false)` is not equal to `true`');
+    assert.ok(!_.isEqual('75', 75), 'String and number primitives with like values are not equal');
+    assert.ok(!_.isEqual(new Number(63), new String(63)), 'String and number objects with like values are not equal');
+    assert.ok(!_.isEqual(75, '75'), 'Commutative equality is implemented for like string and number values');
+    assert.ok(!_.isEqual(0, ''), 'Number and string primitives with like values are not equal');
+    assert.ok(!_.isEqual(1, true), 'Number and boolean primitives with like values are not equal');
+    assert.ok(!_.isEqual(new Boolean(false), new Number(0)), 'Boolean and number objects with like values are not equal');
+    assert.ok(!_.isEqual(false, new String('')), 'Boolean primitives and string objects with like values are not equal');
+    assert.ok(!_.isEqual(12564504e5, new Date(2009, 9, 25)), 'Dates and their corresponding numeric primitive values are not equal');
+
+    // Dates.
+    assert.ok(_.isEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)), 'Date objects referencing identical times are equal');
+    assert.ok(!_.isEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)), 'Date objects referencing different times are not equal');
+    assert.ok(!_.isEqual(new Date(2009, 11, 13), {
+      getTime: function(){
+        return 12606876e5;
+      }
+    }), 'Date objects and objects with a `getTime` method are not equal');
+    assert.ok(!_.isEqual(new Date('Curly'), new Date('Curly')), 'Invalid dates are not equal');
+
+    // Functions.
+    assert.ok(!_.isEqual(First, Second), 'Different functions with identical bodies and source code representations are not equal');
+
+    // RegExps.
+    assert.ok(_.isEqual(/(?:)/gim, /(?:)/gim), 'RegExps with equivalent patterns and flags are equal');
+    assert.ok(_.isEqual(/(?:)/gi, /(?:)/ig), 'Flag order is not significant');
+    assert.ok(!_.isEqual(/(?:)/g, /(?:)/gi), 'RegExps with equivalent patterns and different flags are not equal');
+    assert.ok(!_.isEqual(/Moe/gim, /Curly/gim), 'RegExps with different patterns and equivalent flags are not equal');
+    assert.ok(!_.isEqual(/(?:)/gi, /(?:)/g), 'Commutative equality is implemented for RegExps');
+    assert.ok(!_.isEqual(/Curly/g, {source: 'Larry', global: true, ignoreCase: false, multiline: false}), 'RegExps and RegExp-like objects are not equal');
+
+    // Empty arrays, array-like objects, and object literals.
+    assert.ok(_.isEqual({}, {}), 'Empty object literals are equal');
+    assert.ok(_.isEqual([], []), 'Empty array literals are equal');
+    assert.ok(_.isEqual([{}], [{}]), 'Empty nested arrays and objects are equal');
+    assert.ok(!_.isEqual({length: 0}, []), 'Array-like objects and arrays are not equal.');
+    assert.ok(!_.isEqual([], {length: 0}), 'Commutative equality is implemented for array-like objects');
+
+    assert.ok(!_.isEqual({}, []), 'Object literals and array literals are not equal');
+    assert.ok(!_.isEqual([], {}), 'Commutative equality is implemented for objects and arrays');
+
+    // Arrays with primitive and object values.
+    assert.ok(_.isEqual([1, 'Larry', true], [1, 'Larry', true]), 'Arrays containing identical primitives are equal');
+    assert.ok(_.isEqual([/Moe/g, new Date(2009, 9, 25)], [/Moe/g, new Date(2009, 9, 25)]), 'Arrays containing equivalent elements are equal');
+
+    // Multi-dimensional arrays.
+    var a = [new Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
+    var b = [new Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13), ['running', 'biking', new String('programming')], {a: 47}];
+    assert.ok(_.isEqual(a, b), 'Arrays containing nested arrays and objects are recursively compared');
+
+    // Overwrite the methods defined in ES 5.1 section 15.4.4.
+    a.forEach = a.map = a.filter = a.every = a.indexOf = a.lastIndexOf = a.some = a.reduce = a.reduceRight = null;
+    b.join = b.pop = b.reverse = b.shift = b.slice = b.splice = b.concat = b.sort = b.unshift = null;
+
+    // Array elements and properties.
+    assert.ok(_.isEqual(a, b), 'Arrays containing equivalent elements and different non-numeric properties are equal');
+    a.push('White Rocks');
+    assert.ok(!_.isEqual(a, b), 'Arrays of different lengths are not equal');
+    a.push('East Boulder');
+    b.push('Gunbarrel Ranch', 'Teller Farm');
+    assert.ok(!_.isEqual(a, b), 'Arrays of identical lengths containing different elements are not equal');
+
+    // Sparse arrays.
+    assert.ok(_.isEqual(Array(3), Array(3)), 'Sparse arrays of identical lengths are equal');
+    assert.ok(!_.isEqual(Array(3), Array(6)), 'Sparse arrays of different lengths are not equal when both are empty');
+
+    var sparse = [];
+    sparse[1] = 5;
+    assert.ok(_.isEqual(sparse, [void 0, 5]), 'Handles sparse arrays as dense');
+
+    // Simple objects.
+    assert.ok(_.isEqual({a: 'Curly', b: 1, c: true}, {a: 'Curly', b: 1, c: true}), 'Objects containing identical primitives are equal');
+    assert.ok(_.isEqual({a: /Curly/g, b: new Date(2009, 11, 13)}, {a: /Curly/g, b: new Date(2009, 11, 13)}), 'Objects containing equivalent members are equal');
+    assert.ok(!_.isEqual({a: 63, b: 75}, {a: 61, b: 55}), 'Objects of identical sizes with different values are not equal');
+    assert.ok(!_.isEqual({a: 63, b: 75}, {a: 61, c: 55}), 'Objects of identical sizes with different property names are not equal');
+    assert.ok(!_.isEqual({a: 1, b: 2}, {a: 1}), 'Objects of different sizes are not equal');
+    assert.ok(!_.isEqual({a: 1}, {a: 1, b: 2}), 'Commutative equality is implemented for objects');
+    assert.ok(!_.isEqual({x: 1, y: void 0}, {x: 1, z: 2}), 'Objects with identical keys and different values are not equivalent');
+
+    // `A` contains nested objects and arrays.
+    a = {
+      name: new String('Moe Howard'),
+      age: new Number(77),
+      stooge: true,
+      hobbies: ['acting'],
+      film: {
+        name: 'Sing a Song of Six Pants',
+        release: new Date(1947, 9, 30),
+        stars: [new String('Larry Fine'), 'Shemp Howard'],
+        minutes: new Number(16),
+        seconds: 54
+      }
+    };
+
+    // `B` contains equivalent nested objects and arrays.
+    b = {
+      name: new String('Moe Howard'),
+      age: new Number(77),
+      stooge: true,
+      hobbies: ['acting'],
+      film: {
+        name: 'Sing a Song of Six Pants',
+        release: new Date(1947, 9, 30),
+        stars: [new String('Larry Fine'), 'Shemp Howard'],
+        minutes: new Number(16),
+        seconds: 54
+      }
+    };
+    assert.ok(_.isEqual(a, b), 'Objects with nested equivalent members are recursively compared');
+
+    // Instances.
+    assert.ok(_.isEqual(new First, new First), 'Object instances are equal');
+    assert.ok(!_.isEqual(new First, new Second), 'Objects with different constructors and identical own properties are not equal');
+    assert.ok(!_.isEqual({value: 1}, new First), 'Object instances and objects sharing equivalent properties are not equal');
+    assert.ok(!_.isEqual({value: 2}, new Second), 'The prototype chain of objects should not be examined');
+
+    // Circular Arrays.
+    (a = []).push(a);
+    (b = []).push(b);
+    assert.ok(_.isEqual(a, b), 'Arrays containing circular references are equal');
+    a.push(new String('Larry'));
+    b.push(new String('Larry'));
+    assert.ok(_.isEqual(a, b), 'Arrays containing circular references and equivalent properties are equal');
+    a.push('Shemp');
+    b.push('Curly');
+    assert.ok(!_.isEqual(a, b), 'Arrays containing circular references and different properties are not equal');
+
+    // More circular arrays #767.
+    a = ['everything is checked but', 'this', 'is not'];
+    a[1] = a;
+    b = ['everything is checked but', ['this', 'array'], 'is not'];
+    assert.ok(!_.isEqual(a, b), 'Comparison of circular references with non-circular references are not equal');
+
+    // Circular Objects.
+    a = {abc: null};
+    b = {abc: null};
+    a.abc = a;
+    b.abc = b;
+    assert.ok(_.isEqual(a, b), 'Objects containing circular references are equal');
+    a.def = 75;
+    b.def = 75;
+    assert.ok(_.isEqual(a, b), 'Objects containing circular references and equivalent properties are equal');
+    a.def = new Number(75);
+    b.def = new Number(63);
+    assert.ok(!_.isEqual(a, b), 'Objects containing circular references and different properties are not equal');
+
+    // More circular objects #767.
+    a = {everything: 'is checked', but: 'this', is: 'not'};
+    a.but = a;
+    b = {everything: 'is checked', but: {that: 'object'}, is: 'not'};
+    assert.ok(!_.isEqual(a, b), 'Comparison of circular references with non-circular object references are not equal');
+
+    // Cyclic Structures.
+    a = [{abc: null}];
+    b = [{abc: null}];
+    (a[0].abc = a).push(a);
+    (b[0].abc = b).push(b);
+    assert.ok(_.isEqual(a, b), 'Cyclic structures are equal');
+    a[0].def = 'Larry';
+    b[0].def = 'Larry';
+    assert.ok(_.isEqual(a, b), 'Cyclic structures containing equivalent properties are equal');
+    a[0].def = new String('Larry');
+    b[0].def = new String('Curly');
+    assert.ok(!_.isEqual(a, b), 'Cyclic structures containing different properties are not equal');
+
+    // Complex Circular References.
+    a = {foo: {b: {foo: {c: {foo: null}}}}};
+    b = {foo: {b: {foo: {c: {foo: null}}}}};
+    a.foo.b.foo.c.foo = a;
+    b.foo.b.foo.c.foo = b;
+    assert.ok(_.isEqual(a, b), 'Cyclic structures with nested and identically-named properties are equal');
+
+    // Chaining.
+    assert.ok(!_.isEqual(_({x: 1, y: void 0}).chain(), _({x: 1, z: 2}).chain()), 'Chained objects containing different values are not equal');
+
+    a = _({x: 1, y: 2}).chain();
+    b = _({x: 1, y: 2}).chain();
+    assert.equal(_.isEqual(a.isEqual(b), _(true)), true, '`isEqual` can be chained');
+
+    // Objects without a `constructor` property
+    if (Object.create) {
+      a = Object.create(null, {x: {value: 1, enumerable: true}});
+      b = {x: 1};
+      assert.ok(_.isEqual(a, b), 'Handles objects without a constructor (e.g. from Object.create');
+    }
+
+    function Foo() { this.a = 1; }
+    Foo.prototype.constructor = null;
+
+    var other = {a: 1};
+    assert.strictEqual(_.isEqual(new Foo, other), false, 'Objects from different constructors are not equal');
+
+
+    // Tricky object cases val comparisions
+    assert.equal(_.isEqual([0], [-0]), false);
+    assert.equal(_.isEqual({a: 0}, {a: -0}), false);
+    assert.equal(_.isEqual([NaN], [NaN]), true);
+    assert.equal(_.isEqual({a: NaN}, {a: NaN}), true);
+
+    if (typeof Symbol !== 'undefined') {
+      var symbol = Symbol('x');
+      assert.strictEqual(_.isEqual(symbol, symbol), true, 'A symbol is equal to itself');
+      assert.strictEqual(_.isEqual(symbol, Object(symbol)), true, 'Even when wrapped in Object()');
+      assert.strictEqual(_.isEqual(symbol, null), false, 'Different types are not equal');
+    }
+
+  });
+
+  QUnit.test('isEmpty', function(assert) {
+    assert.ok(!_([1]).isEmpty(), '[1] is not empty');
+    assert.ok(_.isEmpty([]), '[] is empty');
+    assert.ok(!_.isEmpty({one: 1}), '{one: 1} is not empty');
+    assert.ok(_.isEmpty({}), '{} is empty');
+    assert.ok(_.isEmpty(new RegExp('')), 'objects with prototype properties are empty');
+    assert.ok(_.isEmpty(null), 'null is empty');
+    assert.ok(_.isEmpty(), 'undefined is empty');
+    assert.ok(_.isEmpty(''), 'the empty string is empty');
+    assert.ok(!_.isEmpty('moe'), 'but other strings are not');
+
+    var obj = {one: 1};
+    delete obj.one;
+    assert.ok(_.isEmpty(obj), 'deleting all the keys from an object empties it');
+
+    var args = function(){ return arguments; };
+    assert.ok(_.isEmpty(args()), 'empty arguments object is empty');
+    assert.ok(!_.isEmpty(args('')), 'non-empty arguments object is not empty');
+
+    // covers collecting non-enumerable properties in IE < 9
+    var nonEnumProp = {toString: 5};
+    assert.ok(!_.isEmpty(nonEnumProp), 'non-enumerable property is not empty');
+  });
+
+  if (typeof document === 'object') {
+    QUnit.test('isElement', function(assert) {
+      assert.ok(!_.isElement('div'), 'strings are not dom elements');
+      assert.ok(_.isElement(testElement), 'an element is a DOM element');
+    });
+  }
+
+  QUnit.test('isArguments', function(assert) {
+    var args = (function(){ return arguments; }(1, 2, 3));
+    assert.ok(!_.isArguments('string'), 'a string is not an arguments object');
+    assert.ok(!_.isArguments(_.isArguments), 'a function is not an arguments object');
+    assert.ok(_.isArguments(args), 'but the arguments object is an arguments object');
+    assert.ok(!_.isArguments(_.toArray(args)), 'but not when it\'s converted into an array');
+    assert.ok(!_.isArguments([1, 2, 3]), 'and not vanilla arrays.');
+  });
+
+  QUnit.test('isObject', function(assert) {
+    assert.ok(_.isObject(arguments), 'the arguments object is object');
+    assert.ok(_.isObject([1, 2, 3]), 'and arrays');
+    if (testElement) {
+      assert.ok(_.isObject(testElement), 'and DOM element');
+    }
+    assert.ok(_.isObject(function() {}), 'and functions');
+    assert.ok(!_.isObject(null), 'but not null');
+    assert.ok(!_.isObject(void 0), 'and not undefined');
+    assert.ok(!_.isObject('string'), 'and not string');
+    assert.ok(!_.isObject(12), 'and not number');
+    assert.ok(!_.isObject(true), 'and not boolean');
+    assert.ok(_.isObject(new String('string')), 'but new String()');
+  });
+
+  QUnit.test('isArray', function(assert) {
+    assert.ok(!_.isArray(void 0), 'undefined vars are not arrays');
+    assert.ok(!_.isArray(arguments), 'the arguments object is not an array');
+    assert.ok(_.isArray([1, 2, 3]), 'but arrays are');
+  });
+
+  QUnit.test('isString', function(assert) {
+    var obj = new String('I am a string object');
+    if (testElement) {
+      assert.ok(!_.isString(testElement), 'an element is not a string');
+    }
+    assert.ok(_.isString([1, 2, 3].join(', ')), 'but strings are');
+    assert.strictEqual(_.isString('I am a string literal'), true, 'string literals are');
+    assert.ok(_.isString(obj), 'so are String objects');
+    assert.strictEqual(_.isString(1), false);
+  });
+
+  QUnit.test('isSymbol', function(assert) {
+    assert.ok(!_.isSymbol(0), 'numbers are not symbols');
+    assert.ok(!_.isSymbol(''), 'strings are not symbols');
+    assert.ok(!_.isSymbol(_.isSymbol), 'functions are not symbols');
+    if (typeof Symbol === 'function') {
+      assert.ok(_.isSymbol(Symbol()), 'symbols are symbols');
+      assert.ok(_.isSymbol(Symbol('description')), 'described symbols are symbols');
+      assert.ok(_.isSymbol(Object(Symbol())), 'boxed symbols are symbols');
+    }
+  });
+
+  QUnit.test('isNumber', function(assert) {
+    assert.ok(!_.isNumber('string'), 'a string is not a number');
+    assert.ok(!_.isNumber(arguments), 'the arguments object is not a number');
+    assert.ok(!_.isNumber(void 0), 'undefined is not a number');
+    assert.ok(_.isNumber(3 * 4 - 7 / 10), 'but numbers are');
+    assert.ok(_.isNumber(NaN), 'NaN *is* a number');
+    assert.ok(_.isNumber(Infinity), 'Infinity is a number');
+    assert.ok(!_.isNumber('1'), 'numeric strings are not numbers');
+  });
+
+  QUnit.test('isBoolean', function(assert) {
+    assert.ok(!_.isBoolean(2), 'a number is not a boolean');
+    assert.ok(!_.isBoolean('string'), 'a string is not a boolean');
+    assert.ok(!_.isBoolean('false'), 'the string "false" is not a boolean');
+    assert.ok(!_.isBoolean('true'), 'the string "true" is not a boolean');
+    assert.ok(!_.isBoolean(arguments), 'the arguments object is not a boolean');
+    assert.ok(!_.isBoolean(void 0), 'undefined is not a boolean');
+    assert.ok(!_.isBoolean(NaN), 'NaN is not a boolean');
+    assert.ok(!_.isBoolean(null), 'null is not a boolean');
+    assert.ok(_.isBoolean(true), 'but true is');
+    assert.ok(_.isBoolean(false), 'and so is false');
+  });
+
+  QUnit.test('isMap', function(assert) {
+    assert.ok(!_.isMap('string'), 'a string is not a map');
+    assert.ok(!_.isMap(2), 'a number is not a map');
+    assert.ok(!_.isMap({}), 'an object is not a map');
+    assert.ok(!_.isMap(false), 'a boolean is not a map');
+    assert.ok(!_.isMap(void 0), 'undefined is not a map');
+    assert.ok(!_.isMap([1, 2, 3]), 'an array is not a map');
+    if (typeof Set === 'function') {
+      assert.ok(!_.isMap(new Set()), 'a set is not a map');
+    }
+    if (typeof WeakSet === 'function') {
+      assert.ok(!_.isMap(new WeakSet()), 'a weakset is not a map');
+    }
+    if (typeof WeakMap === 'function') {
+      assert.ok(!_.isMap(new WeakMap()), 'a weakmap is not a map');
+    }
+    if (typeof Map === 'function') {
+      var keyString = 'a string';
+      var obj = new Map();
+      obj.set(keyString, 'value');
+      assert.ok(_.isMap(obj), 'but a map is');
+    }
+  });
+
+  QUnit.test('isWeakMap', function(assert) {
+    assert.ok(!_.isWeakMap('string'), 'a string is not a weakmap');
+    assert.ok(!_.isWeakMap(2), 'a number is not a weakmap');
+    assert.ok(!_.isWeakMap({}), 'an object is not a weakmap');
+    assert.ok(!_.isWeakMap(false), 'a boolean is not a weakmap');
+    assert.ok(!_.isWeakMap(void 0), 'undefined is not a weakmap');
+    assert.ok(!_.isWeakMap([1, 2, 3]), 'an array is not a weakmap');
+    if (typeof Set === 'function') {
+      assert.ok(!_.isWeakMap(new Set()), 'a set is not a weakmap');
+    }
+    if (typeof WeakSet === 'function') {
+      assert.ok(!_.isWeakMap(new WeakSet()), 'a weakset is not a weakmap');
+    }
+    if (typeof Map === 'function') {
+      assert.ok(!_.isWeakMap(new Map()), 'a map is not a weakmap');
+    }
+    if (typeof WeakMap === 'function') {
+      var keyObj = {}, obj = new WeakMap();
+      obj.set(keyObj, 'value');
+      assert.ok(_.isWeakMap(obj), 'but a weakmap is');
+    }
+  });
+
+  QUnit.test('isSet', function(assert) {
+    assert.ok(!_.isSet('string'), 'a string is not a set');
+    assert.ok(!_.isSet(2), 'a number is not a set');
+    assert.ok(!_.isSet({}), 'an object is not a set');
+    assert.ok(!_.isSet(false), 'a boolean is not a set');
+    assert.ok(!_.isSet(void 0), 'undefined is not a set');
+    assert.ok(!_.isSet([1, 2, 3]), 'an array is not a set');
+    if (typeof Map === 'function') {
+      assert.ok(!_.isSet(new Map()), 'a map is not a set');
+    }
+    if (typeof WeakMap === 'function') {
+      assert.ok(!_.isSet(new WeakMap()), 'a weakmap is not a set');
+    }
+    if (typeof WeakSet === 'function') {
+      assert.ok(!_.isSet(new WeakSet()), 'a weakset is not a set');
+    }
+    if (typeof Set === 'function') {
+      var obj = new Set();
+      obj.add(1).add('string').add(false).add({});
+      assert.ok(_.isSet(obj), 'but a set is');
+    }
+  });
+
+  QUnit.test('isWeakSet', function(assert) {
+
+    assert.ok(!_.isWeakSet('string'), 'a string is not a weakset');
+    assert.ok(!_.isWeakSet(2), 'a number is not a weakset');
+    assert.ok(!_.isWeakSet({}), 'an object is not a weakset');
+    assert.ok(!_.isWeakSet(false), 'a boolean is not a weakset');
+    assert.ok(!_.isWeakSet(void 0), 'undefined is not a weakset');
+    assert.ok(!_.isWeakSet([1, 2, 3]), 'an array is not a weakset');
+    if (typeof Map === 'function') {
+      assert.ok(!_.isWeakSet(new Map()), 'a map is not a weakset');
+    }
+    if (typeof WeakMap === 'function') {
+      assert.ok(!_.isWeakSet(new WeakMap()), 'a weakmap is not a weakset');
+    }
+    if (typeof Set === 'function') {
+      assert.ok(!_.isWeakSet(new Set()), 'a set is not a weakset');
+    }
+    if (typeof WeakSet === 'function') {
+      var obj = new WeakSet();
+      obj.add({x: 1}, {y: 'string'}).add({y: 'string'}).add({z: [1, 2, 3]});
+      assert.ok(_.isWeakSet(obj), 'but a weakset is');
+    }
+  });
+
+  QUnit.test('isFunction', function(assert) {
+    assert.ok(!_.isFunction(void 0), 'undefined vars are not functions');
+    assert.ok(!_.isFunction([1, 2, 3]), 'arrays are not functions');
+    assert.ok(!_.isFunction('moe'), 'strings are not functions');
+    assert.ok(_.isFunction(_.isFunction), 'but functions are');
+    assert.ok(_.isFunction(function(){}), 'even anonymous ones');
+
+    if (testElement) {
+      assert.ok(!_.isFunction(testElement), 'elements are not functions');
+    }
+
+    var nodelist = typeof document != 'undefined' && document.childNodes;
+    if (nodelist) {
+      assert.ok(!_.isFunction(nodelist));
+    }
+  });
+
+  if (typeof Int8Array !== 'undefined') {
+    QUnit.test('#1929 Typed Array constructors are functions', function(assert) {
+      _.chain(['Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array'])
+      .map(_.propertyOf(typeof GLOBAL != 'undefined' ? GLOBAL : window))
+      .compact()
+      .each(function(TypedArray) {
+        // PhantomJS reports `typeof UInt8Array == 'object'` and doesn't report toString TypeArray
+        // as a function
+        assert.strictEqual(_.isFunction(TypedArray), Object.prototype.toString.call(TypedArray) === '[object Function]');
+      });
+    });
+  }
+
+  QUnit.test('isDate', function(assert) {
+    assert.ok(!_.isDate(100), 'numbers are not dates');
+    assert.ok(!_.isDate({}), 'objects are not dates');
+    assert.ok(_.isDate(new Date()), 'but dates are');
+  });
+
+  QUnit.test('isRegExp', function(assert) {
+    assert.ok(!_.isRegExp(_.identity), 'functions are not RegExps');
+    assert.ok(_.isRegExp(/identity/), 'but RegExps are');
+  });
+
+  QUnit.test('isFinite', function(assert) {
+    assert.ok(!_.isFinite(void 0), 'undefined is not finite');
+    assert.ok(!_.isFinite(null), 'null is not finite');
+    assert.ok(!_.isFinite(NaN), 'NaN is not finite');
+    assert.ok(!_.isFinite(Infinity), 'Infinity is not finite');
+    assert.ok(!_.isFinite(-Infinity), '-Infinity is not finite');
+    assert.ok(_.isFinite('12'), 'Numeric strings are numbers');
+    assert.ok(!_.isFinite('1a'), 'Non numeric strings are not numbers');
+    assert.ok(!_.isFinite(''), 'Empty strings are not numbers');
+    var obj = new Number(5);
+    assert.ok(_.isFinite(obj), 'Number instances can be finite');
+    assert.ok(_.isFinite(0), '0 is finite');
+    assert.ok(_.isFinite(123), 'Ints are finite');
+    assert.ok(_.isFinite(-12.44), 'Floats are finite');
+    if (typeof Symbol === 'function') {
+      assert.ok(!_.isFinite(Symbol()), 'symbols are not numbers');
+      assert.ok(!_.isFinite(Symbol('description')), 'described symbols are not numbers');
+      assert.ok(!_.isFinite(Object(Symbol())), 'boxed symbols are not numbers');
+    }
+  });
+
+  QUnit.test('isNaN', function(assert) {
+    assert.ok(!_.isNaN(void 0), 'undefined is not NaN');
+    assert.ok(!_.isNaN(null), 'null is not NaN');
+    assert.ok(!_.isNaN(0), '0 is not NaN');
+    assert.ok(!_.isNaN(new Number(0)), 'wrapped 0 is not NaN');
+    assert.ok(_.isNaN(NaN), 'but NaN is');
+    assert.ok(_.isNaN(new Number(NaN)), 'wrapped NaN is still NaN');
+  });
+
+  QUnit.test('isNull', function(assert) {
+    assert.ok(!_.isNull(void 0), 'undefined is not null');
+    assert.ok(!_.isNull(NaN), 'NaN is not null');
+    assert.ok(_.isNull(null), 'but null is');
+  });
+
+  QUnit.test('isUndefined', function(assert) {
+    assert.ok(!_.isUndefined(1), 'numbers are defined');
+    assert.ok(!_.isUndefined(null), 'null is defined');
+    assert.ok(!_.isUndefined(false), 'false is defined');
+    assert.ok(!_.isUndefined(NaN), 'NaN is defined');
+    assert.ok(_.isUndefined(), 'nothing is undefined');
+    assert.ok(_.isUndefined(void 0), 'undefined is undefined');
+  });
+
+  QUnit.test('isError', function(assert) {
+    assert.ok(!_.isError(1), 'numbers are not Errors');
+    assert.ok(!_.isError(null), 'null is not an Error');
+    assert.ok(!_.isError(Error), 'functions are not Errors');
+    assert.ok(_.isError(new Error()), 'Errors are Errors');
+    assert.ok(_.isError(new EvalError()), 'EvalErrors are Errors');
+    assert.ok(_.isError(new RangeError()), 'RangeErrors are Errors');
+    assert.ok(_.isError(new ReferenceError()), 'ReferenceErrors are Errors');
+    assert.ok(_.isError(new SyntaxError()), 'SyntaxErrors are Errors');
+    assert.ok(_.isError(new TypeError()), 'TypeErrors are Errors');
+    assert.ok(_.isError(new URIError()), 'URIErrors are Errors');
+  });
+
+  QUnit.test('tap', function(assert) {
+    var intercepted = null;
+    var interceptor = function(obj) { intercepted = obj; };
+    var returned = _.tap(1, interceptor);
+    assert.equal(intercepted, 1, 'passes tapped object to interceptor');
+    assert.equal(returned, 1, 'returns tapped object');
+
+    returned = _([1, 2, 3]).chain().
+      map(function(n){ return n * 2; }).
+      max().
+      tap(interceptor).
+      value();
+    assert.equal(returned, 6, 'can use tapped objects in a chain');
+    assert.equal(intercepted, returned, 'can use tapped objects in a chain');
+  });
+
+  QUnit.test('has', function(assert) {
+    var obj = {foo: 'bar', func: function(){}};
+    assert.ok(_.has(obj, 'foo'), 'has() checks that the object has a property.');
+    assert.ok(!_.has(obj, 'baz'), "has() returns false if the object doesn't have the property.");
+    assert.ok(_.has(obj, 'func'), 'has() works for functions too.');
+    obj.hasOwnProperty = null;
+    assert.ok(_.has(obj, 'foo'), 'has() works even when the hasOwnProperty method is deleted.');
+    var child = {};
+    child.prototype = obj;
+    assert.ok(!_.has(child, 'foo'), 'has() does not check the prototype chain for a property.');
+    assert.strictEqual(_.has(null, 'foo'), false, 'has() returns false for null');
+    assert.strictEqual(_.has(void 0, 'foo'), false, 'has() returns false for undefined');
+  });
+
+  QUnit.test('isMatch', function(assert) {
+    var moe = {name: 'Moe Howard', hair: true};
+    var curly = {name: 'Curly Howard', hair: false};
+
+    assert.equal(_.isMatch(moe, {hair: true}), true, 'Returns a boolean');
+    assert.equal(_.isMatch(curly, {hair: true}), false, 'Returns a boolean');
+
+    assert.equal(_.isMatch(5, {__x__: void 0}), false, 'can match undefined props on primitives');
+    assert.equal(_.isMatch({__x__: void 0}, {__x__: void 0}), true, 'can match undefined props');
+
+    assert.equal(_.isMatch(null, {}), true, 'Empty spec called with null object returns true');
+    assert.equal(_.isMatch(null, {a: 1}), false, 'Non-empty spec called with null object returns false');
+
+    _.each([null, void 0], function(item) { assert.strictEqual(_.isMatch(item, null), true, 'null matches null'); });
+    _.each([null, void 0], function(item) { assert.strictEqual(_.isMatch(item, null), true, 'null matches {}'); });
+    assert.strictEqual(_.isMatch({b: 1}, {a: void 0}), false, 'handles undefined values (1683)');
+
+    _.each([true, 5, NaN, null, void 0], function(item) {
+      assert.strictEqual(_.isMatch({a: 1}, item), true, 'treats primitives as empty');
+    });
+
+    function Prototest() {}
+    Prototest.prototype.x = 1;
+    var specObj = new Prototest;
+    assert.equal(_.isMatch({x: 2}, specObj), true, 'spec is restricted to own properties');
+
+    specObj.y = 5;
+    assert.equal(_.isMatch({x: 1, y: 5}, specObj), true);
+    assert.equal(_.isMatch({x: 1, y: 4}, specObj), false);
+
+    assert.ok(_.isMatch(specObj, {x: 1, y: 5}), 'inherited and own properties are checked on the test object');
+
+    Prototest.x = 5;
+    assert.ok(_.isMatch({x: 5, y: 1}, Prototest), 'spec can be a function');
+
+    //null edge cases
+    var oCon = {constructor: Object};
+    assert.deepEqual(_.map([null, void 0, 5, {}], _.partial(_.isMatch, _, oCon)), [false, false, false, true], 'doesnt falsey match constructor on undefined/null');
+  });
+
+  QUnit.test('matcher', function(assert) {
+    var moe = {name: 'Moe Howard', hair: true};
+    var curly = {name: 'Curly Howard', hair: false};
+    var stooges = [moe, curly];
+
+    assert.equal(_.matcher({hair: true})(moe), true, 'Returns a boolean');
+    assert.equal(_.matcher({hair: true})(curly), false, 'Returns a boolean');
+
+    assert.equal(_.matcher({__x__: void 0})(5), false, 'can match undefined props on primitives');
+    assert.equal(_.matcher({__x__: void 0})({__x__: void 0}), true, 'can match undefined props');
+
+    assert.equal(_.matcher({})(null), true, 'Empty spec called with null object returns true');
+    assert.equal(_.matcher({a: 1})(null), false, 'Non-empty spec called with null object returns false');
+
+    assert.ok(_.find(stooges, _.matcher({hair: false})) === curly, 'returns a predicate that can be used by finding functions.');
+    assert.ok(_.find(stooges, _.matcher(moe)) === moe, 'can be used to locate an object exists in a collection.');
+    assert.deepEqual(_.filter([null, void 0], _.matcher({a: 1})), [], 'Do not throw on null values.');
+
+    assert.deepEqual(_.filter([null, void 0], _.matcher(null)), [null, void 0], 'null matches null');
+    assert.deepEqual(_.filter([null, void 0], _.matcher({})), [null, void 0], 'null matches {}');
+    assert.deepEqual(_.filter([{b: 1}], _.matcher({a: void 0})), [], 'handles undefined values (1683)');
+
+    _.each([true, 5, NaN, null, void 0], function(item) {
+      assert.equal(_.matcher(item)({a: 1}), true, 'treats primitives as empty');
+    });
+
+    function Prototest() {}
+    Prototest.prototype.x = 1;
+    var specObj = new Prototest;
+    var protospec = _.matcher(specObj);
+    assert.equal(protospec({x: 2}), true, 'spec is restricted to own properties');
+
+    specObj.y = 5;
+    protospec = _.matcher(specObj);
+    assert.equal(protospec({x: 1, y: 5}), true);
+    assert.equal(protospec({x: 1, y: 4}), false);
+
+    assert.ok(_.matcher({x: 1, y: 5})(specObj), 'inherited and own properties are checked on the test object');
+
+    Prototest.x = 5;
+    assert.ok(_.matcher(Prototest)({x: 5, y: 1}), 'spec can be a function');
+
+    // #1729
+    var o = {b: 1};
+    var m = _.matcher(o);
+
+    assert.equal(m({b: 1}), true);
+    o.b = 2;
+    o.a = 1;
+    assert.equal(m({b: 1}), true, 'changing spec object doesnt change matches result');
+
+
+    //null edge cases
+    var oCon = _.matcher({constructor: Object});
+    assert.deepEqual(_.map([null, void 0, 5, {}], oCon), [false, false, false, true], 'doesnt falsey match constructor on undefined/null');
+  });
+
+  QUnit.test('matches', function(assert) {
+    assert.strictEqual(_.matches, _.matcher, 'is an alias for matcher');
+  });
+
+  QUnit.test('findKey', function(assert) {
+    var objects = {
+      a: {a: 0, b: 0},
+      b: {a: 1, b: 1},
+      c: {a: 2, b: 2}
+    };
+
+    assert.equal(_.findKey(objects, function(obj) {
+      return obj.a === 0;
+    }), 'a');
+
+    assert.equal(_.findKey(objects, function(obj) {
+      return obj.b * obj.a === 4;
+    }), 'c');
+
+    assert.equal(_.findKey(objects, 'a'), 'b', 'Uses lookupIterator');
+
+    assert.equal(_.findKey(objects, function(obj) {
+      return obj.b * obj.a === 5;
+    }), void 0);
+
+    assert.strictEqual(_.findKey([1, 2, 3, 4, 5, 6], function(obj) {
+      return obj === 3;
+    }), '2', 'Keys are strings');
+
+    assert.strictEqual(_.findKey(objects, function(a) {
+      return a.foo === null;
+    }), void 0);
+
+    _.findKey({a: {a: 1}}, function(a, key, obj) {
+      assert.equal(key, 'a');
+      assert.deepEqual(obj, {a: {a: 1}});
+      assert.strictEqual(this, objects, 'called with context');
+    }, objects);
+
+    var array = [1, 2, 3, 4];
+    array.match = 55;
+    assert.strictEqual(_.findKey(array, function(x) { return x === 55; }), 'match', 'matches array-likes keys');
+  });
+
+
+  QUnit.test('mapObject', function(assert) {
+    var obj = {a: 1, b: 2};
+    var objects = {
+      a: {a: 0, b: 0},
+      b: {a: 1, b: 1},
+      c: {a: 2, b: 2}
+    };
+
+    assert.deepEqual(_.mapObject(obj, function(val) {
+      return val * 2;
+    }), {a: 2, b: 4}, 'simple objects');
+
+    assert.deepEqual(_.mapObject(objects, function(val) {
+      return _.reduce(val, function(memo, v){
+        return memo + v;
+      }, 0);
+    }), {a: 0, b: 2, c: 4}, 'nested objects');
+
+    assert.deepEqual(_.mapObject(obj, function(val, key, o) {
+      return o[key] * 2;
+    }), {a: 2, b: 4}, 'correct keys');
+
+    assert.deepEqual(_.mapObject([1, 2], function(val) {
+      return val * 2;
+    }), {0: 2, 1: 4}, 'check behavior for arrays');
+
+    assert.deepEqual(_.mapObject(obj, function(val) {
+      return val * this.multiplier;
+    }, {multiplier: 3}), {a: 3, b: 6}, 'keep context');
+
+    assert.deepEqual(_.mapObject({a: 1}, function() {
+      return this.length;
+    }, [1, 2]), {a: 2}, 'called with context');
+
+    var ids = _.mapObject({length: 2, 0: {id: '1'}, 1: {id: '2'}}, function(n){
+      return n.id;
+    });
+    assert.deepEqual(ids, {length: void 0, 0: '1', 1: '2'}, 'Check with array-like objects');
+
+    // Passing a property name like _.pluck.
+    var people = {a: {name: 'moe', age: 30}, b: {name: 'curly', age: 50}};
+    assert.deepEqual(_.mapObject(people, 'name'), {a: 'moe', b: 'curly'}, 'predicate string map to object properties');
+
+    _.each([null, void 0, 1, 'abc', [], {}, void 0], function(val){
+      assert.deepEqual(_.mapObject(val, _.identity), {}, 'mapValue identity');
+    });
+
+    var Proto = function(){ this.a = 1; };
+    Proto.prototype.b = 1;
+    var protoObj = new Proto();
+    assert.deepEqual(_.mapObject(protoObj, _.identity), {a: 1}, 'ignore inherited values from prototypes');
+
+  });
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/utility.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/utility.js
new file mode 100644
index 0000000..fbd54df
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/test/utility.js
@@ -0,0 +1,420 @@
+(function() {
+  var _ = typeof require == 'function' ? require('..') : window._;
+  var templateSettings;
+
+  QUnit.module('Utility', {
+
+    beforeEach: function() {
+      templateSettings = _.clone(_.templateSettings);
+    },
+
+    afterEach: function() {
+      _.templateSettings = templateSettings;
+    }
+
+  });
+
+  if (typeof this == 'object') {
+    QUnit.test('noConflict', function(assert) {
+      var underscore = _.noConflict();
+      assert.equal(underscore.identity(1), 1);
+      if (typeof require != 'function') {
+        assert.equal(this._, void 0, 'global underscore is removed');
+        this._ = underscore;
+      } else if (typeof global !== 'undefined') {
+        delete global._;
+      }
+    });
+  }
+
+  if (typeof require == 'function') {
+    QUnit.test('noConflict (node vm)', function(assert) {
+      assert.expect(2);
+      var done = assert.async();
+      var fs = require('fs');
+      var vm = require('vm');
+      var filename = __dirname + '/../underscore.js';
+      fs.readFile(filename, function(err, content){
+        var sandbox = vm.createScript(
+          content + 'this.underscore = this._.noConflict();',
+          filename
+        );
+        var context = {_: 'oldvalue'};
+        sandbox.runInNewContext(context);
+        assert.equal(context._, 'oldvalue');
+        assert.equal(context.underscore.VERSION, _.VERSION);
+
+        done();
+      });
+    });
+  }
+
+  QUnit.test('#750 - Return _ instance.', function(assert) {
+    assert.expect(2);
+    var instance = _([]);
+    assert.ok(_(instance) === instance);
+    assert.ok(new _(instance) === instance);
+  });
+
+  QUnit.test('identity', function(assert) {
+    var stooge = {name: 'moe'};
+    assert.equal(_.identity(stooge), stooge, 'stooge is the same as his identity');
+  });
+
+  QUnit.test('constant', function(assert) {
+    var stooge = {name: 'moe'};
+    assert.equal(_.constant(stooge)(), stooge, 'should create a function that returns stooge');
+  });
+
+  QUnit.test('noop', function(assert) {
+    assert.strictEqual(_.noop('curly', 'larry', 'moe'), void 0, 'should always return undefined');
+  });
+
+  QUnit.test('property', function(assert) {
+    var stooge = {name: 'moe'};
+    assert.equal(_.property('name')(stooge), 'moe', 'should return the property with the given name');
+    assert.equal(_.property('name')(null), void 0, 'should return undefined for null values');
+    assert.equal(_.property('name')(void 0), void 0, 'should return undefined for undefined values');
+  });
+
+  QUnit.test('propertyOf', function(assert) {
+    var stoogeRanks = _.propertyOf({curly: 2, moe: 1, larry: 3});
+    assert.equal(stoogeRanks('curly'), 2, 'should return the property with the given name');
+    assert.equal(stoogeRanks(null), void 0, 'should return undefined for null values');
+    assert.equal(stoogeRanks(void 0), void 0, 'should return undefined for undefined values');
+
+    function MoreStooges() { this.shemp = 87; }
+    MoreStooges.prototype = {curly: 2, moe: 1, larry: 3};
+    var moreStoogeRanks = _.propertyOf(new MoreStooges());
+    assert.equal(moreStoogeRanks('curly'), 2, 'should return properties from further up the prototype chain');
+
+    var nullPropertyOf = _.propertyOf(null);
+    assert.equal(nullPropertyOf('curly'), void 0, 'should return undefined when obj is null');
+
+    var undefPropertyOf = _.propertyOf(void 0);
+    assert.equal(undefPropertyOf('curly'), void 0, 'should return undefined when obj is undefined');
+  });
+
+  QUnit.test('random', function(assert) {
+    var array = _.range(1000);
+    var min = Math.pow(2, 31);
+    var max = Math.pow(2, 62);
+
+    assert.ok(_.every(array, function() {
+      return _.random(min, max) >= min;
+    }), 'should produce a random number greater than or equal to the minimum number');
+
+    assert.ok(_.some(array, function() {
+      return _.random(Number.MAX_VALUE) > 0;
+    }), 'should produce a random number when passed `Number.MAX_VALUE`');
+  });
+
+  QUnit.test('now', function(assert) {
+    var diff = _.now() - new Date().getTime();
+    assert.ok(diff <= 0 && diff > -5, 'Produces the correct time in milliseconds');//within 5ms
+  });
+
+  QUnit.test('uniqueId', function(assert) {
+    var ids = [], i = 0;
+    while (i++ < 100) ids.push(_.uniqueId());
+    assert.equal(_.uniq(ids).length, ids.length, 'can generate a globally-unique stream of ids');
+  });
+
+  QUnit.test('times', function(assert) {
+    var vals = [];
+    _.times(3, function(i) { vals.push(i); });
+    assert.deepEqual(vals, [0, 1, 2], 'is 0 indexed');
+    //
+    vals = [];
+    _(3).times(function(i) { vals.push(i); });
+    assert.deepEqual(vals, [0, 1, 2], 'works as a wrapper');
+    // collects return values
+    assert.deepEqual([0, 1, 2], _.times(3, function(i) { return i; }), 'collects return values');
+
+    assert.deepEqual(_.times(0, _.identity), []);
+    assert.deepEqual(_.times(-1, _.identity), []);
+    assert.deepEqual(_.times(parseFloat('-Infinity'), _.identity), []);
+  });
+
+  QUnit.test('mixin', function(assert) {
+    _.mixin({
+      myReverse: function(string) {
+        return string.split('').reverse().join('');
+      }
+    });
+    assert.equal(_.myReverse('panacea'), 'aecanap', 'mixed in a function to _');
+    assert.equal(_('champ').myReverse(), 'pmahc', 'mixed in a function to the OOP wrapper');
+  });
+
+  QUnit.test('_.escape', function(assert) {
+    assert.equal(_.escape(null), '');
+  });
+
+  QUnit.test('_.unescape', function(assert) {
+    var string = 'Curly & Moe';
+    assert.equal(_.unescape(null), '');
+    assert.equal(_.unescape(_.escape(string)), string);
+    assert.equal(_.unescape(string), string, 'don\'t unescape unnecessarily');
+  });
+
+  // Don't care what they escape them to just that they're escaped and can be unescaped
+  QUnit.test('_.escape & unescape', function(assert) {
+    // test & (&amp;) seperately obviously
+    var escapeCharacters = ['<', '>', '"', '\'', '`'];
+
+    _.each(escapeCharacters, function(escapeChar) {
+      var s = 'a ' + escapeChar + ' string escaped';
+      var e = _.escape(s);
+      assert.notEqual(s, e, escapeChar + ' is escaped');
+      assert.equal(s, _.unescape(e), escapeChar + ' can be unescaped');
+
+      s = 'a ' + escapeChar + escapeChar + escapeChar + 'some more string' + escapeChar;
+      e = _.escape(s);
+
+      assert.equal(e.indexOf(escapeChar), -1, 'can escape multiple occurances of ' + escapeChar);
+      assert.equal(_.unescape(e), s, 'multiple occurrences of ' + escapeChar + ' can be unescaped');
+    });
+
+    // handles multiple escape characters at once
+    var joiner = ' other stuff ';
+    var allEscaped = escapeCharacters.join(joiner);
+    allEscaped += allEscaped;
+    assert.ok(_.every(escapeCharacters, function(escapeChar) {
+      return allEscaped.indexOf(escapeChar) !== -1;
+    }), 'handles multiple characters');
+    assert.ok(allEscaped.indexOf(joiner) >= 0, 'can escape multiple escape characters at the same time');
+
+    // test & -> &amp;
+    var str = 'some string & another string & yet another';
+    var escaped = _.escape(str);
+
+    assert.ok(escaped.indexOf('&') !== -1, 'handles & aka &amp;');
+    assert.equal(_.unescape(str), str, 'can unescape &amp;');
+  });
+
+  QUnit.test('template', function(assert) {
+    var basicTemplate = _.template("<%= thing %> is gettin' on my noives!");
+    var result = basicTemplate({thing: 'This'});
+    assert.equal(result, "This is gettin' on my noives!", 'can do basic attribute interpolation');
+
+    var sansSemicolonTemplate = _.template('A <% this %> B');
+    assert.equal(sansSemicolonTemplate(), 'A  B');
+
+    var backslashTemplate = _.template('<%= thing %> is \\ridanculous');
+    assert.equal(backslashTemplate({thing: 'This'}), 'This is \\ridanculous');
+
+    var escapeTemplate = _.template('<%= a ? "checked=\\"checked\\"" : "" %>');
+    assert.equal(escapeTemplate({a: true}), 'checked="checked"', 'can handle slash escapes in interpolations.');
+
+    var fancyTemplate = _.template('<ul><% ' +
+    '  for (var key in people) { ' +
+    '%><li><%= people[key] %></li><% } %></ul>');
+    result = fancyTemplate({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
+    assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
+
+    var escapedCharsInJavascriptTemplate = _.template('<ul><% _.each(numbers.split("\\n"), function(item) { %><li><%= item %></li><% }) %></ul>');
+    result = escapedCharsInJavascriptTemplate({numbers: 'one\ntwo\nthree\nfour'});
+    assert.equal(result, '<ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>', 'Can use escaped characters (e.g. \\n) in JavaScript');
+
+    var namespaceCollisionTemplate = _.template('<%= pageCount %> <%= thumbnails[pageCount] %> <% _.each(thumbnails, function(p) { %><div class="thumbnail" rel="<%= p %>"></div><% }); %>');
+    result = namespaceCollisionTemplate({
+      pageCount: 3,
+      thumbnails: {
+        1: 'p1-thumbnail.gif',
+        2: 'p2-thumbnail.gif',
+        3: 'p3-thumbnail.gif'
+      }
+    });
+    assert.equal(result, '3 p3-thumbnail.gif <div class="thumbnail" rel="p1-thumbnail.gif"></div><div class="thumbnail" rel="p2-thumbnail.gif"></div><div class="thumbnail" rel="p3-thumbnail.gif"></div>');
+
+    var noInterpolateTemplate = _.template('<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
+    result = noInterpolateTemplate();
+    assert.equal(result, '<div><p>Just some text. Hey, I know this is silly but it aids consistency.</p></div>');
+
+    var quoteTemplate = _.template("It's its, not it's");
+    assert.equal(quoteTemplate({}), "It's its, not it's");
+
+    var quoteInStatementAndBody = _.template('<% ' +
+    "  if(foo == 'bar'){ " +
+    "%>Statement quotes and 'quotes'.<% } %>");
+    assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
+
+    var withNewlinesAndTabs = _.template('This\n\t\tis: <%= x %>.\n\tok.\nend.');
+    assert.equal(withNewlinesAndTabs({x: 'that'}), 'This\n\t\tis: that.\n\tok.\nend.');
+
+    var template = _.template('<i><%- value %></i>');
+    result = template({value: '<script>'});
+    assert.equal(result, '<i>&lt;script&gt;</i>');
+
+    var stooge = {
+      name: 'Moe',
+      template: _.template("I'm <%= this.name %>")
+    };
+    assert.equal(stooge.template(), "I'm Moe");
+
+    template = _.template('\n ' +
+    '  <%\n ' +
+    '  // a comment\n ' +
+    '  if (data) { data += 12345; }; %>\n ' +
+    '  <li><%= data %></li>\n '
+    );
+    assert.equal(template({data: 12345}).replace(/\s/g, ''), '<li>24690</li>');
+
+    _.templateSettings = {
+      evaluate: /\{\{([\s\S]+?)\}\}/g,
+      interpolate: /\{\{=([\s\S]+?)\}\}/g
+    };
+
+    var custom = _.template('<ul>{{ for (var key in people) { }}<li>{{= people[key] }}</li>{{ } }}</ul>');
+    result = custom({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
+    assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
+
+    var customQuote = _.template("It's its, not it's");
+    assert.equal(customQuote({}), "It's its, not it's");
+
+    quoteInStatementAndBody = _.template("{{ if(foo == 'bar'){ }}Statement quotes and 'quotes'.{{ } }}");
+    assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
+
+    _.templateSettings = {
+      evaluate: /<\?([\s\S]+?)\?>/g,
+      interpolate: /<\?=([\s\S]+?)\?>/g
+    };
+
+    var customWithSpecialChars = _.template('<ul><? for (var key in people) { ?><li><?= people[key] ?></li><? } ?></ul>');
+    result = customWithSpecialChars({people: {moe: 'Moe', larry: 'Larry', curly: 'Curly'}});
+    assert.equal(result, '<ul><li>Moe</li><li>Larry</li><li>Curly</li></ul>', 'can run arbitrary javascript in templates');
+
+    var customWithSpecialCharsQuote = _.template("It's its, not it's");
+    assert.equal(customWithSpecialCharsQuote({}), "It's its, not it's");
+
+    quoteInStatementAndBody = _.template("<? if(foo == 'bar'){ ?>Statement quotes and 'quotes'.<? } ?>");
+    assert.equal(quoteInStatementAndBody({foo: 'bar'}), "Statement quotes and 'quotes'.");
+
+    _.templateSettings = {
+      interpolate: /\{\{(.+?)\}\}/g
+    };
+
+    var mustache = _.template('Hello {{planet}}!');
+    assert.equal(mustache({planet: 'World'}), 'Hello World!', 'can mimic mustache.js');
+
+    var templateWithNull = _.template('a null undefined {{planet}}');
+    assert.equal(templateWithNull({planet: 'world'}), 'a null undefined world', 'can handle missing escape and evaluate settings');
+  });
+
+  QUnit.test('_.template provides the generated function source, when a SyntaxError occurs', function(assert) {
+    var source;
+    try {
+      _.template('<b><%= if x %></b>');
+    } catch (ex) {
+      source = ex.source;
+    }
+    assert.ok(/__p/.test(source));
+  });
+
+  QUnit.test('_.template handles \\u2028 & \\u2029', function(assert) {
+    var tmpl = _.template('<p>\u2028<%= "\\u2028\\u2029" %>\u2029</p>');
+    assert.strictEqual(tmpl(), '<p>\u2028\u2028\u2029\u2029</p>');
+  });
+
+  QUnit.test('result calls functions and returns primitives', function(assert) {
+    var obj = {w: '', x: 'x', y: function(){ return this.x; }};
+    assert.strictEqual(_.result(obj, 'w'), '');
+    assert.strictEqual(_.result(obj, 'x'), 'x');
+    assert.strictEqual(_.result(obj, 'y'), 'x');
+    assert.strictEqual(_.result(obj, 'z'), void 0);
+    assert.strictEqual(_.result(null, 'x'), void 0);
+  });
+
+  QUnit.test('result returns a default value if object is null or undefined', function(assert) {
+    assert.strictEqual(_.result(null, 'b', 'default'), 'default');
+    assert.strictEqual(_.result(void 0, 'c', 'default'), 'default');
+    assert.strictEqual(_.result(''.match('missing'), 1, 'default'), 'default');
+  });
+
+  QUnit.test('result returns a default value if property of object is missing', function(assert) {
+    assert.strictEqual(_.result({d: null}, 'd', 'default'), null);
+    assert.strictEqual(_.result({e: false}, 'e', 'default'), false);
+  });
+
+  QUnit.test('result only returns the default value if the object does not have the property or is undefined', function(assert) {
+    assert.strictEqual(_.result({}, 'b', 'default'), 'default');
+    assert.strictEqual(_.result({d: void 0}, 'd', 'default'), 'default');
+  });
+
+  QUnit.test('result does not return the default if the property of an object is found in the prototype', function(assert) {
+    var Foo = function(){};
+    Foo.prototype.bar = 1;
+    assert.strictEqual(_.result(new Foo, 'bar', 2), 1);
+  });
+
+  QUnit.test('result does use the fallback when the result of invoking the property is undefined', function(assert) {
+    var obj = {a: function() {}};
+    assert.strictEqual(_.result(obj, 'a', 'failed'), void 0);
+  });
+
+  QUnit.test('result fallback can use a function', function(assert) {
+    var obj = {a: [1, 2, 3]};
+    assert.strictEqual(_.result(obj, 'b', _.constant(5)), 5);
+    assert.strictEqual(_.result(obj, 'b', function() {
+      return this.a;
+    }), obj.a, 'called with context');
+  });
+
+  QUnit.test('_.templateSettings.variable', function(assert) {
+    var s = '<%=data.x%>';
+    var data = {x: 'x'};
+    var tmp = _.template(s, {variable: 'data'});
+    assert.strictEqual(tmp(data), 'x');
+    _.templateSettings.variable = 'data';
+    assert.strictEqual(_.template(s)(data), 'x');
+  });
+
+  QUnit.test('#547 - _.templateSettings is unchanged by custom settings.', function(assert) {
+    assert.ok(!_.templateSettings.variable);
+    _.template('', {}, {variable: 'x'});
+    assert.ok(!_.templateSettings.variable);
+  });
+
+  QUnit.test('#556 - undefined template variables.', function(assert) {
+    var template = _.template('<%=x%>');
+    assert.strictEqual(template({x: null}), '');
+    assert.strictEqual(template({x: void 0}), '');
+
+    var templateEscaped = _.template('<%-x%>');
+    assert.strictEqual(templateEscaped({x: null}), '');
+    assert.strictEqual(templateEscaped({x: void 0}), '');
+
+    var templateWithProperty = _.template('<%=x.foo%>');
+    assert.strictEqual(templateWithProperty({x: {}}), '');
+    assert.strictEqual(templateWithProperty({x: {}}), '');
+
+    var templateWithPropertyEscaped = _.template('<%-x.foo%>');
+    assert.strictEqual(templateWithPropertyEscaped({x: {}}), '');
+    assert.strictEqual(templateWithPropertyEscaped({x: {}}), '');
+  });
+
+  QUnit.test('interpolate evaluates code only once.', function(assert) {
+    assert.expect(2);
+    var count = 0;
+    var template = _.template('<%= f() %>');
+    template({f: function(){ assert.ok(!count++); }});
+
+    var countEscaped = 0;
+    var templateEscaped = _.template('<%- f() %>');
+    templateEscaped({f: function(){ assert.ok(!countEscaped++); }});
+  });
+
+  QUnit.test('#746 - _.template settings are not modified.', function(assert) {
+    assert.expect(1);
+    var settings = {};
+    _.template('', null, settings);
+    assert.deepEqual(settings, {});
+  });
+
+  QUnit.test('#779 - delimeters are applied to unescaped text.', function(assert) {
+    assert.expect(1);
+    var template = _.template('<<\nx\n>>', null, {evaluate: /<<(.*?)>>/g});
+    assert.strictEqual(template(), '<<\nx\n>>');
+  });
+
+}());
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/underscore-min.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/underscore-min.js
new file mode 100644
index 0000000..f01025b
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/underscore-min.js
@@ -0,0 +1,6 @@
+//     Underscore.js 1.8.3
+//     http://underscorejs.org
+//     (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     Underscore may be freely distributed under the MIT license.
+(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])<u?i=a+1:o=a}return i},m.indexOf=r(1,m.findIndex,m.sortedIndex),m.lastIndexOf=r(-1,m.findLastIndex),m.range=function(n,t,r){null==t&&(t=n||0,n=0),r=r||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),i=0;e>i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e<arguments.length;)i.push(arguments[e++]);return E(n,r,this,this,i)};return r},m.bindAll=function(n){var t,r,e=arguments.length;if(1>=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this);
+//# sourceMappingURL=underscore-min.map
\ No newline at end of file
diff --git a/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/underscore.js b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/underscore.js
new file mode 100644
index 0000000..bddfdc9
--- /dev/null
+++ b/views/ngXosViews/serviceGrid/src/vendor/lodash/vendor/underscore/underscore.js
@@ -0,0 +1,1620 @@
+//     Underscore.js 1.8.3
+//     http://underscorejs.org
+//     (c) 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+//     Underscore may be freely distributed under the MIT license.
+
+(function() {
+
+  // Baseline setup
+  // --------------
+
+  // Establish the root object, `window` (`self`) in the browser, `global`
+  // on the server, or `this` in some virtual machines. We use `self`
+  // instead of `window` for `WebWorker` support.
+  var root = typeof self == 'object' && self.self === self && self ||
+            typeof global == 'object' && global.global === global && global ||
+            this;
+
+  // Save the previous value of the `_` variable.
+  var previousUnderscore = root._;
+
+  // Save bytes in the minified (but not gzipped) version:
+  var ArrayProto = Array.prototype, ObjProto = Object.prototype;
+  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
+
+  // Create quick reference variables for speed access to core prototypes.
+  var push = ArrayProto.push,
+      slice = ArrayProto.slice,
+      toString = ObjProto.toString,
+      hasOwnProperty = ObjProto.hasOwnProperty;
+
+  // All **ECMAScript 5** native function implementations that we hope to use
+  // are declared here.
+  var nativeIsArray = Array.isArray,
+      nativeKeys = Object.keys,
+      nativeCreate = Object.create;
+
+  // Naked function reference for surrogate-prototype-swapping.
+  var Ctor = function(){};
+
+  // Create a safe reference to the Underscore object for use below.
+  var _ = function(obj) {
+    if (obj instanceof _) return obj;
+    if (!(this instanceof _)) return new _(obj);
+    this._wrapped = obj;
+  };
+
+  // Export the Underscore object for **Node.js**, with
+  // backwards-compatibility for their old module API. If we're in
+  // the browser, add `_` as a global object.
+  // (`nodeType` is checked to ensure that `module`
+  // and `exports` are not HTML elements.)
+  if (typeof exports != 'undefined' && !exports.nodeType) {
+    if (typeof module != 'undefined' && !module.nodeType && module.exports) {
+      exports = module.exports = _;
+    }
+    exports._ = _;
+  } else {
+    root._ = _;
+  }
+
+  // Current version.
+  _.VERSION = '1.8.3';
+
+  // Internal function that returns an efficient (for current engines) version
+  // of the passed-in callback, to be repeatedly applied in other Underscore
+  // functions.
+  var optimizeCb = function(func, context, argCount) {
+    if (context === void 0) return func;
+    switch (argCount == null ? 3 : argCount) {
+      case 1: return function(value) {
+        return func.call(context, value);
+      };
+      // The 2-parameter case has been omitted only because no current consumers
+      // made use of it.
+      case 3: return function(value, index, collection) {
+        return func.call(context, value, index, collection);
+      };
+      case 4: return function(accumulator, value, index, collection) {
+        return func.call(context, accumulator, value, index, collection);
+      };
+    }
+    return function() {
+      return func.apply(context, arguments);
+    };
+  };
+
+  // An internal function to generate callbacks that can be applied to each
+  // element in a collection, returning the desired result — either `identity`,
+  // an arbitrary callback, a property matcher, or a property accessor.
+  var cb = function(value, context, argCount) {
+    if (value == null) return _.identity;
+    if (_.isFunction(value)) return optimizeCb(value, context, argCount);
+    if (_.isObject(value)) return _.matcher(value);
+    return _.property(value);
+  };
+
+  // An external wrapper for the internal callback generator.
+  _.iteratee = function(value, context) {
+    return cb(value, context, Infinity);
+  };
+
+  // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
+  // This accumulates the arguments passed into an array, after a given index.
+  var restArgs = function(func, startIndex) {
+    startIndex = startIndex == null ? func.length - 1 : +startIndex;
+    return function() {
+      var length = Math.max(arguments.length - startIndex, 0);
+      var rest = Array(length);
+      for (var index = 0; index < length; index++) {
+        rest[index] = arguments[index + startIndex];
+      }
+      switch (startIndex) {
+        case 0: return func.call(this, rest);
+        case 1: return func.call(this, arguments[0], rest);
+        case 2: return func.call(this, arguments[0], arguments[1], rest);
+      }
+      var args = Array(startIndex + 1);
+      for (index = 0; index < startIndex; index++) {
+        args[index] = arguments[index];
+      }
+      args[startIndex] = rest;
+      return func.apply(this, args);
+    };
+  };
+
+  // An internal function for creating a new object that inherits from another.
+  var baseCreate = function(prototype) {
+    if (!_.isObject(prototype)) return {};
+    if (nativeCreate) return nativeCreate(prototype);
+    Ctor.prototype = prototype;
+    var result = new Ctor;
+    Ctor.prototype = null;
+    return result;
+  };
+
+  var property = function(key) {
+    return function(obj) {
+      return obj == null ? void 0 : obj[key];
+    };
+  };
+
+  // Helper for collection methods to determine whether a collection
+  // should be iterated as an array or as an object.
+  // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
+  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
+  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
+  var getLength = property('length');
+  var isArrayLike = function(collection) {
+    var length = getLength(collection);
+    return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
+  };
+
+  // Collection Functions
+  // --------------------
+
+  // The cornerstone, an `each` implementation, aka `forEach`.
+  // Handles raw objects in addition to array-likes. Treats all
+  // sparse array-likes as if they were dense.
+  _.each = _.forEach = function(obj, iteratee, context) {
+    iteratee = optimizeCb(iteratee, context);
+    var i, length;
+    if (isArrayLike(obj)) {
+      for (i = 0, length = obj.length; i < length; i++) {
+        iteratee(obj[i], i, obj);
+      }
+    } else {
+      var keys = _.keys(obj);
+      for (i = 0, length = keys.length; i < length; i++) {
+        iteratee(obj[keys[i]], keys[i], obj);
+      }
+    }
+    return obj;
+  };
+
+  // Return the results of applying the iteratee to each element.
+  _.map = _.collect = function(obj, iteratee, context) {
+    iteratee = cb(iteratee, context);
+    var keys = !isArrayLike(obj) && _.keys(obj),
+        length = (keys || obj).length,
+        results = Array(length);
+    for (var index = 0; index < length; index++) {
+      var currentKey = keys ? keys[index] : index;
+      results[index] = iteratee(obj[currentKey], currentKey, obj);
+    }
+    return results;
+  };
+
+  // Create a reducing function iterating left or right.
+  var createReduce = function(dir) {
+    // Wrap code that reassigns argument variables in a separate function than
+    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
+    var reducer = function(obj, iteratee, memo, initial) {
+      var keys = !isArrayLike(obj) && _.keys(obj),
+          length = (keys || obj).length,
+          index = dir > 0 ? 0 : length - 1;
+      if (!initial) {
+        memo = obj[keys ? keys[index] : index];
+        index += dir;
+      }
+      for (; index >= 0 && index < length; index += dir) {
+        var currentKey = keys ? keys[index] : index;
+        memo = iteratee(memo, obj[currentKey], currentKey, obj);
+      }
+      return memo;
+    };
+
+    return function(obj, iteratee, memo, context) {
+      var initial = arguments.length >= 3;
+      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
+    };
+  };
+
+  // **Reduce** builds up a single result from a list of values, aka `inject`,
+  // or `foldl`.
+  _.reduce = _.foldl = _.inject = createReduce(1);
+
+  // The right-associative version of reduce, also known as `foldr`.
+  _.reduceRight = _.foldr = createReduce(-1);
+
+  // Return the first value which passes a truth test. Aliased as `detect`.
+  _.find = _.detect = function(obj, predicate, context) {
+    var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey;
+    var key = keyFinder(obj, predicate, context);
+    if (key !== void 0 && key !== -1) return obj[key];
+  };
+
+  // Return all the elements that pass a truth test.
+  // Aliased as `select`.
+  _.filter = _.select = function(obj, predicate, context) {
+    var results = [];
+    predicate = cb(predicate, context);
+    _.each(obj, function(value, index, list) {
+      if (predicate(value, index, list)) results.push(value);
+    });
+    return results;
+  };
+
+  // Return all the elements for which a truth test fails.
+  _.reject = function(obj, predicate, context) {
+    return _.filter(obj, _.negate(cb(predicate)), context);
+  };
+
+  // Determine whether all of the elements match a truth test.
+  // Aliased as `all`.
+  _.every = _.all = function(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var keys = !isArrayLike(obj) && _.keys(obj),
+        length = (keys || obj).length;
+    for (var index = 0; index < length; index++) {
+      var currentKey = keys ? keys[index] : index;
+      if (!predicate(obj[currentKey], currentKey, obj)) return false;
+    }
+    return true;
+  };
+
+  // Determine if at least one element in the object matches a truth test.
+  // Aliased as `any`.
+  _.some = _.any = function(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var keys = !isArrayLike(obj) && _.keys(obj),
+        length = (keys || obj).length;
+    for (var index = 0; index < length; index++) {
+      var currentKey = keys ? keys[index] : index;
+      if (predicate(obj[currentKey], currentKey, obj)) return true;
+    }
+    return false;
+  };
+
+  // Determine if the array or object contains a given item (using `===`).
+  // Aliased as `includes` and `include`.
+  _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) {
+    if (!isArrayLike(obj)) obj = _.values(obj);
+    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
+    return _.indexOf(obj, item, fromIndex) >= 0;
+  };
+
+  // Invoke a method (with arguments) on every item in a collection.
+  _.invoke = restArgs(function(obj, method, args) {
+    var isFunc = _.isFunction(method);
+    return _.map(obj, function(value) {
+      var func = isFunc ? method : value[method];
+      return func == null ? func : func.apply(value, args);
+    });
+  });
+
+  // Convenience version of a common use case of `map`: fetching a property.
+  _.pluck = function(obj, key) {
+    return _.map(obj, _.property(key));
+  };
+
+  // Convenience version of a common use case of `filter`: selecting only objects
+  // containing specific `key:value` pairs.
+  _.where = function(obj, attrs) {
+    return _.filter(obj, _.matcher(attrs));
+  };
+
+  // Convenience version of a common use case of `find`: getting the first object
+  // containing specific `key:value` pairs.
+  _.findWhere = function(obj, attrs) {
+    return _.find(obj, _.matcher(attrs));
+  };
+
+  // Return the maximum element (or element-based computation).
+  _.max = function(obj, iteratee, context) {
+    var result = -Infinity, lastComputed = -Infinity,
+        value, computed;
+    if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object') && obj != null) {
+      obj = isArrayLike(obj) ? obj : _.values(obj);
+      for (var i = 0, length = obj.length; i < length; i++) {
+        value = obj[i];
+        if (value != null && value > result) {
+          result = value;
+        }
+      }
+    } else {
+      iteratee = cb(iteratee, context);
+      _.each(obj, function(v, index, list) {
+        computed = iteratee(v, index, list);
+        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
+          result = v;
+          lastComputed = computed;
+        }
+      });
+    }
+    return result;
+  };
+
+  // Return the minimum element (or element-based computation).
+  _.min = function(obj, iteratee, context) {
+    var result = Infinity, lastComputed = Infinity,
+        value, computed;
+    if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object') && obj != null) {
+      obj = isArrayLike(obj) ? obj : _.values(obj);
+      for (var i = 0, length = obj.length; i < length; i++) {
+        value = obj[i];
+        if (value != null && value < result) {
+          result = value;
+        }
+      }
+    } else {
+      iteratee = cb(iteratee, context);
+      _.each(obj, function(v, index, list) {
+        computed = iteratee(v, index, list);
+        if (computed < lastComputed || computed === Infinity && result === Infinity) {
+          result = v;
+          lastComputed = computed;
+        }
+      });
+    }
+    return result;
+  };
+
+  // Shuffle a collection.
+  _.shuffle = function(obj) {
+    return _.sample(obj, Infinity);
+  };
+
+  // Sample **n** random values from a collection using the modern version of the
+  // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
+  // If **n** is not specified, returns a single random element.
+  // The internal `guard` argument allows it to work with `map`.
+  _.sample = function(obj, n, guard) {
+    if (n == null || guard) {
+      if (!isArrayLike(obj)) obj = _.values(obj);
+      return obj[_.random(obj.length - 1)];
+    }
+    var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj);
+    var length = getLength(sample);
+    n = Math.max(Math.min(n, length), 0);
+    var last = length - 1;
+    for (var index = 0; index < n; index++) {
+      var rand = _.random(index, last);
+      var temp = sample[index];
+      sample[index] = sample[rand];
+      sample[rand] = temp;
+    }
+    return sample.slice(0, n);
+  };
+
+  // Sort the object's values by a criterion produced by an iteratee.
+  _.sortBy = function(obj, iteratee, context) {
+    var index = 0;
+    iteratee = cb(iteratee, context);
+    return _.pluck(_.map(obj, function(value, key, list) {
+      return {
+        value: value,
+        index: index++,
+        criteria: iteratee(value, key, list)
+      };
+    }).sort(function(left, right) {
+      var a = left.criteria;
+      var b = right.criteria;
+      if (a !== b) {
+        if (a > b || a === void 0) return 1;
+        if (a < b || b === void 0) return -1;
+      }
+      return left.index - right.index;
+    }), 'value');
+  };
+
+  // An internal function used for aggregate "group by" operations.
+  var group = function(behavior, partition) {
+    return function(obj, iteratee, context) {
+      var result = partition ? [[], []] : {};
+      iteratee = cb(iteratee, context);
+      _.each(obj, function(value, index) {
+        var key = iteratee(value, index, obj);
+        behavior(result, value, key);
+      });
+      return result;
+    };
+  };
+
+  // Groups the object's values by a criterion. Pass either a string attribute
+  // to group by, or a function that returns the criterion.
+  _.groupBy = group(function(result, value, key) {
+    if (_.has(result, key)) result[key].push(value); else result[key] = [value];
+  });
+
+  // Indexes the object's values by a criterion, similar to `groupBy`, but for
+  // when you know that your index values will be unique.
+  _.indexBy = group(function(result, value, key) {
+    result[key] = value;
+  });
+
+  // Counts instances of an object that group by a certain criterion. Pass
+  // either a string attribute to count by, or a function that returns the
+  // criterion.
+  _.countBy = group(function(result, value, key) {
+    if (_.has(result, key)) result[key]++; else result[key] = 1;
+  });
+
+  var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
+  // Safely create a real, live array from anything iterable.
+  _.toArray = function(obj) {
+    if (!obj) return [];
+    if (_.isArray(obj)) return slice.call(obj);
+    if (_.isString(obj)) {
+      // Keep surrogate pair characters together
+      return obj.match(reStrSymbol);
+    }
+    if (isArrayLike(obj)) return _.map(obj);
+    return _.values(obj);
+  };
+
+  // Return the number of elements in an object.
+  _.size = function(obj) {
+    if (obj == null) return 0;
+    return isArrayLike(obj) ? obj.length : _.keys(obj).length;
+  };
+
+  // Split a collection into two arrays: one whose elements all satisfy the given
+  // predicate, and one whose elements all do not satisfy the predicate.
+  _.partition = group(function(result, value, pass) {
+    result[pass ? 0 : 1].push(value);
+  }, true);
+
+  // Array Functions
+  // ---------------
+
+  // Get the first element of an array. Passing **n** will return the first N
+  // values in the array. Aliased as `head` and `take`. The **guard** check
+  // allows it to work with `_.map`.
+  _.first = _.head = _.take = function(array, n, guard) {
+    if (array == null) return void 0;
+    if (n == null || guard) return array[0];
+    return _.initial(array, array.length - n);
+  };
+
+  // Returns everything but the last entry of the array. Especially useful on
+  // the arguments object. Passing **n** will return all the values in
+  // the array, excluding the last N.
+  _.initial = function(array, n, guard) {
+    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
+  };
+
+  // Get the last element of an array. Passing **n** will return the last N
+  // values in the array.
+  _.last = function(array, n, guard) {
+    if (array == null) return void 0;
+    if (n == null || guard) return array[array.length - 1];
+    return _.rest(array, Math.max(0, array.length - n));
+  };
+
+  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
+  // Especially useful on the arguments object. Passing an **n** will return
+  // the rest N values in the array.
+  _.rest = _.tail = _.drop = function(array, n, guard) {
+    return slice.call(array, n == null || guard ? 1 : n);
+  };
+
+  // Trim out all falsy values from an array.
+  _.compact = function(array) {
+    return _.filter(array);
+  };
+
+  // Internal implementation of a recursive `flatten` function.
+  var flatten = function(input, shallow, strict, output) {
+    output = output || [];
+    var idx = output.length;
+    for (var i = 0, length = getLength(input); i < length; i++) {
+      var value = input[i];
+      if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) {
+        // Flatten current level of array or arguments object.
+        if (shallow) {
+          var j = 0, len = value.length;
+          while (j < len) output[idx++] = value[j++];
+        } else {
+          flatten(value, shallow, strict, output);
+          idx = output.length;
+        }
+      } else if (!strict) {
+        output[idx++] = value;
+      }
+    }
+    return output;
+  };
+
+  // Flatten out an array, either recursively (by default), or just one level.
+  _.flatten = function(array, shallow) {
+    return flatten(array, shallow, false);
+  };
+
+  // Return a version of the array that does not contain the specified value(s).
+  _.without = restArgs(function(array, otherArrays) {
+    return _.difference(array, otherArrays);
+  });
+
+  // Produce a duplicate-free version of the array. If the array has already
+  // been sorted, you have the option of using a faster algorithm.
+  // Aliased as `unique`.
+  _.uniq = _.unique = function(array, isSorted, iteratee, context) {
+    if (!_.isBoolean(isSorted)) {
+      context = iteratee;
+      iteratee = isSorted;
+      isSorted = false;
+    }
+    if (iteratee != null) iteratee = cb(iteratee, context);
+    var result = [];
+    var seen = [];
+    for (var i = 0, length = getLength(array); i < length; i++) {
+      var value = array[i],
+          computed = iteratee ? iteratee(value, i, array) : value;
+      if (isSorted) {
+        if (!i || seen !== computed) result.push(value);
+        seen = computed;
+      } else if (iteratee) {
+        if (!_.contains(seen, computed)) {
+          seen.push(computed);
+          result.push(value);
+        }
+      } else if (!_.contains(result, value)) {
+        result.push(value);
+      }
+    }
+    return result;
+  };
+
+  // Produce an array that contains the union: each distinct element from all of
+  // the passed-in arrays.
+  _.union = restArgs(function(arrays) {
+    return _.uniq(flatten(arrays, true, true));
+  });
+
+  // Produce an array that contains every item shared between all the
+  // passed-in arrays.
+  _.intersection = function(array) {
+    var result = [];
+    var argsLength = arguments.length;
+    for (var i = 0, length = getLength(array); i < length; i++) {
+      var item = array[i];
+      if (_.contains(result, item)) continue;
+      var j;
+      for (j = 1; j < argsLength; j++) {
+        if (!_.contains(arguments[j], item)) break;
+      }
+      if (j === argsLength) result.push(item);
+    }
+    return result;
+  };
+
+  // Take the difference between one array and a number of other arrays.
+  // Only the elements present in just the first array will remain.
+  _.difference = restArgs(function(array, rest) {
+    rest = flatten(rest, true, true);
+    return _.filter(array, function(value){
+      return !_.contains(rest, value);
+    });
+  });
+
+  // Complement of _.zip. Unzip accepts an array of arrays and groups
+  // each array's elements on shared indices.
+  _.unzip = function(array) {
+    var length = array && _.max(array, getLength).length || 0;
+    var result = Array(length);
+
+    for (var index = 0; index < length; index++) {
+      result[index] = _.pluck(array, index);
+    }
+    return result;
+  };
+
+  // Zip together multiple lists into a single array -- elements that share
+  // an index go together.
+  _.zip = restArgs(_.unzip);
+
+  // Converts lists into objects. Pass either a single array of `[key, value]`
+  // pairs, or two parallel arrays of the same length -- one of keys, and one of
+  // the corresponding values.
+  _.object = function(list, values) {
+    var result = {};
+    for (var i = 0, length = getLength(list); i < length; i++) {
+      if (values) {
+        result[list[i]] = values[i];
+      } else {
+        result[list[i][0]] = list[i][1];
+      }
+    }
+    return result;
+  };
+
+  // Generator function to create the findIndex and findLastIndex functions.
+  var createPredicateIndexFinder = function(dir) {
+    return function(array, predicate, context) {
+      predicate = cb(predicate, context);
+      var length = getLength(array);
+      var index = dir > 0 ? 0 : length - 1;
+      for (; index >= 0 && index < length; index += dir) {
+        if (predicate(array[index], index, array)) return index;
+      }
+      return -1;
+    };
+  };
+
+  // Returns the first index on an array-like that passes a predicate test.
+  _.findIndex = createPredicateIndexFinder(1);
+  _.findLastIndex = createPredicateIndexFinder(-1);
+
+  // Use a comparator function to figure out the smallest index at which
+  // an object should be inserted so as to maintain order. Uses binary search.
+  _.sortedIndex = function(array, obj, iteratee, context) {
+    iteratee = cb(iteratee, context, 1);
+    var value = iteratee(obj);
+    var low = 0, high = getLength(array);
+    while (low < high) {
+      var mid = Math.floor((low + high) / 2);
+      if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
+    }
+    return low;
+  };
+
+  // Generator function to create the indexOf and lastIndexOf functions.
+  var createIndexFinder = function(dir, predicateFind, sortedIndex) {
+    return function(array, item, idx) {
+      var i = 0, length = getLength(array);
+      if (typeof idx == 'number') {
+        if (dir > 0) {
+          i = idx >= 0 ? idx : Math.max(idx + length, i);
+        } else {
+          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
+        }
+      } else if (sortedIndex && idx && length) {
+        idx = sortedIndex(array, item);
+        return array[idx] === item ? idx : -1;
+      }
+      if (item !== item) {
+        idx = predicateFind(slice.call(array, i, length), _.isNaN);
+        return idx >= 0 ? idx + i : -1;
+      }
+      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
+        if (array[idx] === item) return idx;
+      }
+      return -1;
+    };
+  };
+
+  // Return the position of the first occurrence of an item in an array,
+  // or -1 if the item is not included in the array.
+  // If the array is large and already in sort order, pass `true`
+  // for **isSorted** to use binary search.
+  _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex);
+  _.lastIndexOf = createIndexFinder(-1, _.findLastIndex);
+
+  // Generate an integer Array containing an arithmetic progression. A port of
+  // the native Python `range()` function. See
+  // [the Python documentation](http://docs.python.org/library/functions.html#range).
+  _.range = function(start, stop, step) {
+    if (stop == null) {
+      stop = start || 0;
+      start = 0;
+    }
+    if (!step) {
+      step = stop < start ? -1 : 1;
+    }
+
+    var length = Math.max(Math.ceil((stop - start) / step), 0);
+    var range = Array(length);
+
+    for (var idx = 0; idx < length; idx++, start += step) {
+      range[idx] = start;
+    }
+
+    return range;
+  };
+
+  // Split an **array** into several arrays containing **count** or less elements
+  // of initial array.
+  _.chunk = function(array, count) {
+    if (count == null || count < 1) return [];
+
+    var result = [];
+    var i = 0, length = array.length;
+    while (i < length) {
+      result.push(slice.call(array, i, i += count));
+    }
+    return result;
+  };
+
+  // Function (ahem) Functions
+  // ------------------
+
+  // Determines whether to execute a function as a constructor
+  // or a normal function with the provided arguments.
+  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
+    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
+    var self = baseCreate(sourceFunc.prototype);
+    var result = sourceFunc.apply(self, args);
+    if (_.isObject(result)) return result;
+    return self;
+  };
+
+  // Create a function bound to a given object (assigning `this`, and arguments,
+  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
+  // available.
+  _.bind = restArgs(function(func, context, args) {
+    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
+    var bound = restArgs(function(callArgs) {
+      return executeBound(func, bound, context, this, args.concat(callArgs));
+    });
+    return bound;
+  });
+
+  // Partially apply a function by creating a version that has had some of its
+  // arguments pre-filled, without changing its dynamic `this` context. _ acts
+  // as a placeholder by default, allowing any combination of arguments to be
+  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
+  _.partial = restArgs(function(func, boundArgs) {
+    var placeholder = _.partial.placeholder;
+    var bound = function() {
+      var position = 0, length = boundArgs.length;
+      var args = Array(length);
+      for (var i = 0; i < length; i++) {
+        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
+      }
+      while (position < arguments.length) args.push(arguments[position++]);
+      return executeBound(func, bound, this, this, args);
+    };
+    return bound;
+  });
+
+  _.partial.placeholder = _;
+
+  // Bind a number of an object's methods to that object. Remaining arguments
+  // are the method names to be bound. Useful for ensuring that all callbacks
+  // defined on an object belong to it.
+  _.bindAll = restArgs(function(obj, keys) {
+    keys = flatten(keys, false, false);
+    var index = keys.length;
+    if (index < 1) throw new Error('bindAll must be passed function names');
+    while (index--) {
+      var key = keys[index];
+      obj[key] = _.bind(obj[key], obj);
+    }
+  });
+
+  // Memoize an expensive function by storing its results.
+  _.memoize = function(func, hasher) {
+    var memoize = function(key) {
+      var cache = memoize.cache;
+      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
+      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
+      return cache[address];
+    };
+    memoize.cache = {};
+    return memoize;
+  };
+
+  // Delays a function for the given number of milliseconds, and then calls
+  // it with the arguments supplied.
+  _.delay = restArgs(function(func, wait, args) {
+    return setTimeout(function() {
+      return func.apply(null, args);
+    }, wait);
+  });
+
+  // Defers a function, scheduling it to run after the current call stack has
+  // cleared.
+  _.defer = _.partial(_.delay, _, 1);
+
+  // Returns a function, that, when invoked, will only be triggered at most once
+  // during a given window of time. Normally, the throttled function will run
+  // as much as it can, without ever going more than once per `wait` duration;
+  // but if you'd like to disable the execution on the leading edge, pass
+  // `{leading: false}`. To disable execution on the trailing edge, ditto.
+  _.throttle = function(func, wait, options) {
+    var timeout, context, args, result;
+    var previous = 0;
+    if (!options) options = {};
+
+    var later = function() {
+      previous = options.leading === false ? 0 : _.now();
+      timeout = null;
+      result = func.apply(context, args);
+      if (!timeout) context = args = null;
+    };
+
+    var throttled = function() {
+      var now = _.now();
+      if (!previous && options.leading === false) previous = now;
+      var remaining = wait - (now - previous);
+      context = this;
+      args = arguments;
+      if (remaining <= 0 || remaining > wait) {
+        if (timeout) {
+          clearTimeout(timeout);
+          timeout = null;
+        }
+        previous = now;
+        result = func.apply(context, args);
+        if (!timeout) context = args = null;
+      } else if (!timeout && options.trailing !== false) {
+        timeout = setTimeout(later, remaining);
+      }
+      return result;
+    };
+
+    throttled.cancel = function() {
+      clearTimeout(timeout);
+      previous = 0;
+      timeout = context = args = null;
+    };
+
+    return throttled;
+  };
+
+  // Returns a function, that, as long as it continues to be invoked, will not
+  // be triggered. The function will be called after it stops being called for
+  // N milliseconds. If `immediate` is passed, trigger the function on the
+  // leading edge, instead of the trailing.
+  _.debounce = function(func, wait, immediate) {
+    var timeout, result;
+
+    var later = function(context, args) {
+      timeout = null;
+      if (args) result = func.apply(context, args);
+    };
+
+    var debounced = restArgs(function(args) {
+      if (timeout) clearTimeout(timeout);
+      if (immediate) {
+        var callNow = !timeout;
+        timeout = setTimeout(later, wait);
+        if (callNow) result = func.apply(this, args);
+      } else {
+        timeout = _.delay(later, wait, this, args);
+      }
+
+      return result;
+    });
+
+    debounced.cancel = function() {
+      clearTimeout(timeout);
+      timeout = null;
+    };
+
+    return debounced;
+  };
+
+  // Returns the first function passed as an argument to the second,
+  // allowing you to adjust arguments, run code before and after, and
+  // conditionally execute the original function.
+  _.wrap = function(func, wrapper) {
+    return _.partial(wrapper, func);
+  };
+
+  // Returns a negated version of the passed-in predicate.
+  _.negate = function(predicate) {
+    return function() {
+      return !predicate.apply(this, arguments);
+    };
+  };
+
+  // Returns a function that is the composition of a list of functions, each
+  // consuming the return value of the function that follows.
+  _.compose = function() {
+    var args = arguments;
+    var start = args.length - 1;
+    return function() {
+      var i = start;
+      var result = args[start].apply(this, arguments);
+      while (i--) result = args[i].call(this, result);
+      return result;
+    };
+  };
+
+  // Returns a function that will only be executed on and after the Nth call.
+  _.after = function(times, func) {
+    return function() {
+      if (--times < 1) {
+        return func.apply(this, arguments);
+      }
+    };
+  };
+
+  // Returns a function that will only be executed up to (but not including) the Nth call.
+  _.before = function(times, func) {
+    var memo;
+    return function() {
+      if (--times > 0) {
+        memo = func.apply(this, arguments);
+      }
+      if (times <= 1) func = null;
+      return memo;
+    };
+  };
+
+  // Returns a function that will be executed at most one time, no matter how
+  // often you call it. Useful for lazy initialization.
+  _.once = _.partial(_.before, 2);
+
+  _.restArgs = restArgs;
+
+  // Object Functions
+  // ----------------
+
+  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
+  var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
+  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
+                      'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
+
+  var collectNonEnumProps = function(obj, keys) {
+    var nonEnumIdx = nonEnumerableProps.length;
+    var constructor = obj.constructor;
+    var proto = _.isFunction(constructor) && constructor.prototype || ObjProto;
+
+    // Constructor is a special case.
+    var prop = 'constructor';
+    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);
+
+    while (nonEnumIdx--) {
+      prop = nonEnumerableProps[nonEnumIdx];
+      if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
+        keys.push(prop);
+      }
+    }
+  };
+
+  // Retrieve the names of an object's own properties.
+  // Delegates to **ECMAScript 5**'s native `Object.keys`.
+  _.keys = function(obj) {
+    if (!_.isObject(obj)) return [];
+    if (nativeKeys) return nativeKeys(obj);
+    var keys = [];
+    for (var key in obj) if (_.has(obj, key)) keys.push(key);
+    // Ahem, IE < 9.
+    if (hasEnumBug) collectNonEnumProps(obj, keys);
+    return keys;
+  };
+
+  // Retrieve all the property names of an object.
+  _.allKeys = function(obj) {
+    if (!_.isObject(obj)) return [];
+    var keys = [];
+    for (var key in obj) keys.push(key);
+    // Ahem, IE < 9.
+    if (hasEnumBug) collectNonEnumProps(obj, keys);
+    return keys;
+  };
+
+  // Retrieve the values of an object's properties.
+  _.values = function(obj) {
+    var keys = _.keys(obj);
+    var length = keys.length;
+    var values = Array(length);
+    for (var i = 0; i < length; i++) {
+      values[i] = obj[keys[i]];
+    }
+    return values;
+  };
+
+  // Returns the results of applying the iteratee to each element of the object.
+  // In contrast to _.map it returns an object.
+  _.mapObject = function(obj, iteratee, context) {
+    iteratee = cb(iteratee, context);
+    var keys = _.keys(obj),
+        length = keys.length,
+        results = {};
+    for (var index = 0; index < length; index++) {
+      var currentKey = keys[index];
+      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
+    }
+    return results;
+  };
+
+  // Convert an object into a list of `[key, value]` pairs.
+  _.pairs = function(obj) {
+    var keys = _.keys(obj);
+    var length = keys.length;
+    var pairs = Array(length);
+    for (var i = 0; i < length; i++) {
+      pairs[i] = [keys[i], obj[keys[i]]];
+    }
+    return pairs;
+  };
+
+  // Invert the keys and values of an object. The values must be serializable.
+  _.invert = function(obj) {
+    var result = {};
+    var keys = _.keys(obj);
+    for (var i = 0, length = keys.length; i < length; i++) {
+      result[obj[keys[i]]] = keys[i];
+    }
+    return result;
+  };
+
+  // Return a sorted list of the function names available on the object.
+  // Aliased as `methods`.
+  _.functions = _.methods = function(obj) {
+    var names = [];
+    for (var key in obj) {
+      if (_.isFunction(obj[key])) names.push(key);
+    }
+    return names.sort();
+  };
+
+  // An internal function for creating assigner functions.
+  var createAssigner = function(keysFunc, defaults) {
+    return function(obj) {
+      var length = arguments.length;
+      if (defaults) obj = Object(obj);
+      if (length < 2 || obj == null) return obj;
+      for (var index = 1; index < length; index++) {
+        var source = arguments[index],
+            keys = keysFunc(source),
+            l = keys.length;
+        for (var i = 0; i < l; i++) {
+          var key = keys[i];
+          if (!defaults || obj[key] === void 0) obj[key] = source[key];
+        }
+      }
+      return obj;
+    };
+  };
+
+  // Extend a given object with all the properties in passed-in object(s).
+  _.extend = createAssigner(_.allKeys);
+
+  // Assigns a given object with all the own properties in the passed-in object(s).
+  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
+  _.extendOwn = _.assign = createAssigner(_.keys);
+
+  // Returns the first key on an object that passes a predicate test.
+  _.findKey = function(obj, predicate, context) {
+    predicate = cb(predicate, context);
+    var keys = _.keys(obj), key;
+    for (var i = 0, length = keys.length; i < length; i++) {
+      key = keys[i];
+      if (predicate(obj[key], key, obj)) return key;
+    }
+  };
+
+  // Internal pick helper function to determine if `obj` has key `key`.
+  var keyInObj = function(value, key, obj) {
+    return key in obj;
+  };
+
+  // Return a copy of the object only containing the whitelisted properties.
+  _.pick = restArgs(function(obj, keys) {
+    var result = {}, iteratee = keys[0];
+    if (obj == null) return result;
+    if (_.isFunction(iteratee)) {
+      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
+      keys = _.allKeys(obj);
+    } else {
+      iteratee = keyInObj;
+      keys = flatten(keys, false, false);
+      obj = Object(obj);
+    }
+    for (var i = 0, length = keys.length; i < length; i++) {
+      var key = keys[i];
+      var value = obj[key];
+      if (iteratee(value, key, obj)) result[key] = value;
+    }
+    return result;
+  });
+
+   // Return a copy of the object without the blacklisted properties.
+  _.omit = restArgs(function(obj, keys) {
+    var iteratee = keys[0], context;
+    if (_.isFunction(iteratee)) {
+      iteratee = _.negate(iteratee);
+      if (keys.length > 1) context = keys[1];
+    } else {
+      keys = _.map(flatten(keys, false, false), String);
+      iteratee = function(value, key) {
+        return !_.contains(keys, key);
+      };
+    }
+    return _.pick(obj, iteratee, context);
+  });
+
+  // Fill in a given object with default properties.
+  _.defaults = createAssigner(_.allKeys, true);
+
+  // Creates an object that inherits from the given prototype object.
+  // If additional properties are provided then they will be added to the
+  // created object.
+  _.create = function(prototype, props) {
+    var result = baseCreate(prototype);
+    if (props) _.extendOwn(result, props);
+    return result;
+  };
+
+  // Create a (shallow-cloned) duplicate of an object.
+  _.clone = function(obj) {
+    if (!_.isObject(obj)) return obj;
+    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
+  };
+
+  // Invokes interceptor with the obj, and then returns obj.
+  // The primary purpose of this method is to "tap into" a method chain, in
+  // order to perform operations on intermediate results within the chain.
+  _.tap = function(obj, interceptor) {
+    interceptor(obj);
+    return obj;
+  };
+
+  // Returns whether an object has a given set of `key:value` pairs.
+  _.isMatch = function(object, attrs) {
+    var keys = _.keys(attrs), length = keys.length;
+    if (object == null) return !length;
+    var obj = Object(object);
+    for (var i = 0; i < length; i++) {
+      var key = keys[i];
+      if (attrs[key] !== obj[key] || !(key in obj)) return false;
+    }
+    return true;
+  };
+
+
+  // Internal recursive comparison function for `isEqual`.
+  var eq, deepEq;
+  eq = function(a, b, aStack, bStack) {
+    // Identical objects are equal. `0 === -0`, but they aren't identical.
+    // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
+    if (a === b) return a !== 0 || 1 / a === 1 / b;
+    // A strict comparison is necessary because `null == undefined`.
+    if (a == null || b == null) return a === b;
+    // `NaN`s are equivalent, but non-reflexive.
+    if (a !== a) return b !== b;
+    // Exhaust primitive checks
+    var type = typeof a;
+    if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
+    return deepEq(a, b, aStack, bStack);
+  };
+
+  // Internal recursive comparison function for `isEqual`.
+  deepEq = function(a, b, aStack, bStack) {
+    // Unwrap any wrapped objects.
+    if (a instanceof _) a = a._wrapped;
+    if (b instanceof _) b = b._wrapped;
+    // Compare `[[Class]]` names.
+    var className = toString.call(a);
+    if (className !== toString.call(b)) return false;
+    switch (className) {
+      // Strings, numbers, regular expressions, dates, and booleans are compared by value.
+      case '[object RegExp]':
+      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
+      case '[object String]':
+        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
+        // equivalent to `new String("5")`.
+        return '' + a === '' + b;
+      case '[object Number]':
+        // `NaN`s are equivalent, but non-reflexive.
+        // Object(NaN) is equivalent to NaN.
+        if (+a !== +a) return +b !== +b;
+        // An `egal` comparison is performed for other numeric values.
+        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
+      case '[object Date]':
+      case '[object Boolean]':
+        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
+        // millisecond representations. Note that invalid dates with millisecond representations
+        // of `NaN` are not equivalent.
+        return +a === +b;
+      case '[object Symbol]':
+        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
+    }
+
+    var areArrays = className === '[object Array]';
+    if (!areArrays) {
+      if (typeof a != 'object' || typeof b != 'object') return false;
+
+      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
+      // from different frames are.
+      var aCtor = a.constructor, bCtor = b.constructor;
+      if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor &&
+                               _.isFunction(bCtor) && bCtor instanceof bCtor)
+                          && ('constructor' in a && 'constructor' in b)) {
+        return false;
+      }
+    }
+    // Assume equality for cyclic structures. The algorithm for detecting cyclic
+    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
+
+    // Initializing stack of traversed objects.
+    // It's done here since we only need them for objects and arrays comparison.
+    aStack = aStack || [];
+    bStack = bStack || [];
+    var length = aStack.length;
+    while (length--) {
+      // Linear search. Performance is inversely proportional to the number of
+      // unique nested structures.
+      if (aStack[length] === a) return bStack[length] === b;
+    }
+
+    // Add the first object to the stack of traversed objects.
+    aStack.push(a);
+    bStack.push(b);
+
+    // Recursively compare objects and arrays.
+    if (areArrays) {
+      // Compare array lengths to determine if a deep comparison is necessary.
+      length = a.length;
+      if (length !== b.length) return false;
+      // Deep compare the contents, ignoring non-numeric properties.
+      while (length--) {
+        if (!eq(a[length], b[length], aStack, bStack)) return false;
+      }
+    } else {
+      // Deep compare objects.
+      var keys = _.keys(a), key;
+      length = keys.length;
+      // Ensure that both objects contain the same number of properties before comparing deep equality.
+      if (_.keys(b).length !== length) return false;
+      while (length--) {
+        // Deep compare each member
+        key = keys[length];
+        if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
+      }
+    }
+    // Remove the first object from the stack of traversed objects.
+    aStack.pop();
+    bStack.pop();
+    return true;
+  };
+
+  // Perform a deep comparison to check if two objects are equal.
+  _.isEqual = function(a, b) {
+    return eq(a, b);
+  };
+
+  // Is a given array, string, or object empty?
+  // An "empty" object has no enumerable own-properties.
+  _.isEmpty = function(obj) {
+    if (obj == null) return true;
+    if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0;
+    return _.keys(obj).length === 0;
+  };
+
+  // Is a given value a DOM element?
+  _.isElement = function(obj) {
+    return !!(obj && obj.nodeType === 1);
+  };
+
+  // Is a given value an array?
+  // Delegates to ECMA5's native Array.isArray
+  _.isArray = nativeIsArray || function(obj) {
+    return toString.call(obj) === '[object Array]';
+  };
+
+  // Is a given variable an object?
+  _.isObject = function(obj) {
+    var type = typeof obj;
+    return type === 'function' || type === 'object' && !!obj;
+  };
+
+  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet.
+  _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) {
+    _['is' + name] = function(obj) {
+      return toString.call(obj) === '[object ' + name + ']';
+    };
+  });
+
+  // Define a fallback version of the method in browsers (ahem, IE < 9), where
+  // there isn't any inspectable "Arguments" type.
+  if (!_.isArguments(arguments)) {
+    _.isArguments = function(obj) {
+      return _.has(obj, 'callee');
+    };
+  }
+
+  // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8,
+  // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
+  var nodelist = root.document && root.document.childNodes;
+  if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
+    _.isFunction = function(obj) {
+      return typeof obj == 'function' || false;
+    };
+  }
+
+  // Is a given object a finite number?
+  _.isFinite = function(obj) {
+    return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj));
+  };
+
+  // Is the given value `NaN`?
+  _.isNaN = function(obj) {
+    return _.isNumber(obj) && isNaN(obj);
+  };
+
+  // Is a given value a boolean?
+  _.isBoolean = function(obj) {
+    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
+  };
+
+  // Is a given value equal to null?
+  _.isNull = function(obj) {
+    return obj === null;
+  };
+
+  // Is a given variable undefined?
+  _.isUndefined = function(obj) {
+    return obj === void 0;
+  };
+
+  // Shortcut function for checking if an object has a given property directly
+  // on itself (in other words, not on a prototype).
+  _.has = function(obj, key) {
+    return obj != null && hasOwnProperty.call(obj, key);
+  };
+
+  // Utility Functions
+  // -----------------
+
+  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
+  // previous owner. Returns a reference to the Underscore object.
+  _.noConflict = function() {
+    root._ = previousUnderscore;
+    return this;
+  };
+
+  // Keep the identity function around for default iteratees.
+  _.identity = function(value) {
+    return value;
+  };
+
+  // Predicate-generating functions. Often useful outside of Underscore.
+  _.constant = function(value) {
+    return function() {
+      return value;
+    };
+  };
+
+  _.noop = function(){};
+
+  _.property = property;
+
+  // Generates a function for a given object that returns a given property.
+  _.propertyOf = function(obj) {
+    return obj == null ? function(){} : function(key) {
+      return obj[key];
+    };
+  };
+
+  // Returns a predicate for checking whether an object has a given set of
+  // `key:value` pairs.
+  _.matcher = _.matches = function(attrs) {
+    attrs = _.extendOwn({}, attrs);
+    return function(obj) {
+      return _.isMatch(obj, attrs);
+    };
+  };
+
+  // Run a function **n** times.
+  _.times = function(n, iteratee, context) {
+    var accum = Array(Math.max(0, n));
+    iteratee = optimizeCb(iteratee, context, 1);
+    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
+    return accum;
+  };
+
+  // Return a random integer between min and max (inclusive).
+  _.random = function(min, max) {
+    if (max == null) {
+      max = min;
+      min = 0;
+    }
+    return min + Math.floor(Math.random() * (max - min + 1));
+  };
+
+  // A (possibly faster) way to get the current timestamp as an integer.
+  _.now = Date.now || function() {
+    return new Date().getTime();
+  };
+
+   // List of HTML entities for escaping.
+  var escapeMap = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#x27;',
+    '`': '&#x60;'
+  };
+  var unescapeMap = _.invert(escapeMap);
+
+  // Functions for escaping and unescaping strings to/from HTML interpolation.
+  var createEscaper = function(map) {
+    var escaper = function(match) {
+      return map[match];
+    };
+    // Regexes for identifying a key that needs to be escaped.
+    var source = '(?:' + _.keys(map).join('|') + ')';
+    var testRegexp = RegExp(source);
+    var replaceRegexp = RegExp(source, 'g');
+    return function(string) {
+      string = string == null ? '' : '' + string;
+      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
+    };
+  };
+  _.escape = createEscaper(escapeMap);
+  _.unescape = createEscaper(unescapeMap);
+
+  // If the value of the named `property` is a function then invoke it with the
+  // `object` as context; otherwise, return it.
+  _.result = function(object, prop, fallback) {
+    var value = object == null ? void 0 : object[prop];
+    if (value === void 0) {
+      value = fallback;
+    }
+    return _.isFunction(value) ? value.call(object) : value;
+  };
+
+  // Generate a unique integer id (unique within the entire client session).
+  // Useful for temporary DOM ids.
+  var idCounter = 0;
+  _.uniqueId = function(prefix) {
+    var id = ++idCounter + '';
+    return prefix ? prefix + id : id;
+  };
+
+  // By default, Underscore uses ERB-style template delimiters, change the
+  // following template settings to use alternative delimiters.
+  _.templateSettings = {
+    evaluate: /<%([\s\S]+?)%>/g,
+    interpolate: /<%=([\s\S]+?)%>/g,
+    escape: /<%-([\s\S]+?)%>/g
+  };
+
+  // When customizing `templateSettings`, if you don't want to define an
+  // interpolation, evaluation or escaping regex, we need one that is
+  // guaranteed not to match.
+  var noMatch = /(.)^/;
+
+  // Certain characters need to be escaped so that they can be put into a
+  // string literal.
+  var escapes = {
+    "'": "'",
+    '\\': '\\',
+    '\r': 'r',
+    '\n': 'n',
+    '\u2028': 'u2028',
+    '\u2029': 'u2029'
+  };
+
+  var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
+
+  var escapeChar = function(match) {
+    return '\\' + escapes[match];
+  };
+
+  // JavaScript micro-templating, similar to John Resig's implementation.
+  // Underscore templating handles arbitrary delimiters, preserves whitespace,
+  // and correctly escapes quotes within interpolated code.
+  // NB: `oldSettings` only exists for backwards compatibility.
+  _.template = function(text, settings, oldSettings) {
+    if (!settings && oldSettings) settings = oldSettings;
+    settings = _.defaults({}, settings, _.templateSettings);
+
+    // Combine delimiters into one regular expression via alternation.
+    var matcher = RegExp([
+      (settings.escape || noMatch).source,
+      (settings.interpolate || noMatch).source,
+      (settings.evaluate || noMatch).source
+    ].join('|') + '|$', 'g');
+
+    // Compile the template source, escaping string literals appropriately.
+    var index = 0;
+    var source = "__p+='";
+    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
+      index = offset + match.length;
+
+      if (escape) {
+        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+      } else if (interpolate) {
+        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+      } else if (evaluate) {
+        source += "';\n" + evaluate + "\n__p+='";
+      }
+
+      // Adobe VMs need the match returned to produce the correct offset.
+      return match;
+    });
+    source += "';\n";
+
+    // If a variable is not specified, place data values in local scope.
+    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+    source = "var __t,__p='',__j=Array.prototype.join," +
+      "print=function(){__p+=__j.call(arguments,'');};\n" +
+      source + 'return __p;\n';
+
+    var render;
+    try {
+      render = new Function(settings.variable || 'obj', '_', source);
+    } catch (e) {
+      e.source = source;
+      throw e;
+    }
+
+    var template = function(data) {
+      return render.call(this, data, _);
+    };
+
+    // Provide the compiled source as a convenience for precompilation.
+    var argument = settings.variable || 'obj';
+    template.source = 'function(' + argument + '){\n' + source + '}';
+
+    return template;
+  };
+
+  // Add a "chain" function. Start chaining a wrapped Underscore object.
+  _.chain = function(obj) {
+    var instance = _(obj);
+    instance._chain = true;
+    return instance;
+  };
+
+  // OOP
+  // ---------------
+  // If Underscore is called as a function, it returns a wrapped object that
+  // can be used OO-style. This wrapper holds altered versions of all the
+  // underscore functions. Wrapped objects may be chained.
+
+  // Helper function to continue chaining intermediate results.
+  var chainResult = function(instance, obj) {
+    return instance._chain ? _(obj).chain() : obj;
+  };
+
+  // Add your own custom functions to the Underscore object.
+  _.mixin = function(obj) {
+    _.each(_.functions(obj), function(name) {
+      var func = _[name] = obj[name];
+      _.prototype[name] = function() {
+        var args = [this._wrapped];
+        push.apply(args, arguments);
+        return chainResult(this, func.apply(_, args));
+      };
+    });
+  };
+
+  // Add all of the Underscore functions to the wrapper object.
+  _.mixin(_);
+
+  // Add all mutator Array functions to the wrapper.
+  _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
+    var method = ArrayProto[name];
+    _.prototype[name] = function() {
+      var obj = this._wrapped;
+      method.apply(obj, arguments);
+      if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0];
+      return chainResult(this, obj);
+    };
+  });
+
+  // Add all accessor Array functions to the wrapper.
+  _.each(['concat', 'join', 'slice'], function(name) {
+    var method = ArrayProto[name];
+    _.prototype[name] = function() {
+      return chainResult(this, method.apply(this._wrapped, arguments));
+    };
+  });
+
+  // Extracts the result from a wrapped and chained object.
+  _.prototype.value = function() {
+    return this._wrapped;
+  };
+
+  // Provide unwrapping proxy for some methods used in engine operations
+  // such as arithmetic and JSON stringification.
+  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
+
+  _.prototype.toString = function() {
+    return '' + this._wrapped;
+  };
+
+  // AMD registration happens at the end for compatibility with AMD loaders
+  // that may not enforce next-turn semantics on modules. Even though general
+  // practice for AMD registration is to be anonymous, underscore registers
+  // as a named module because, like jQuery, it is a base library that is
+  // popular enough to be bundled in a third party lib, but not be part of
+  // an AMD load request. Those cases could generate an error when an
+  // anonymous define() is called outside of a loader request.
+  if (typeof define == 'function' && define.amd) {
+    define('underscore', [], function() {
+      return _;
+    });
+  }
+}());
