couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From met...@apache.org
Subject [04/10] update lodash
Date Thu, 28 Mar 2013 22:44:45 GMT
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1c601bb5/src/fauxton/assets/js/libs/lodash.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/lodash.js b/src/fauxton/assets/js/libs/lodash.js
index 43ddcb2..ccf632d 100644
--- a/src/fauxton/assets/js/libs/lodash.js
+++ b/src/fauxton/assets/js/libs/lodash.js
@@ -1,77 +1,77 @@
-/*!
- * Lo-Dash v0.3.1 <http://lodash.com>
- * Copyright 2012 John-David Dalton <http://allyoucanleet.com/>
- * Based on Underscore.js 1.3.3, copyright 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
- * <http://documentcloud.github.com/underscore>
+/**
+ * @license
+ * Lo-Dash 1.1.1 (Custom Build) <http://lodash.com/>
+ * Build: `lodash underscore exports="amd,commonjs,global,node" -o ./dist/lodash.underscore.js`
+ * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
+ * Based on Underscore.js 1.4.4 <http://underscorejs.org/>
+ * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
  * Available under MIT license <http://lodash.com/license>
  */
-;(function(window, undefined) {
-  'use strict';
+;(function(window) {
+
+  /** Used as a safe reference for `undefined` in pre ES5 environments */
+  var undefined;
 
   /** Detect free variable `exports` */
-  var freeExports = typeof exports == 'object' && exports &&
-    (typeof global == 'object' && global && global == global.global && (window = global), exports);
+  var freeExports = typeof exports == 'object' && exports;
 
-  /**
-   * Detect the JScript [[DontEnum]] bug:
-   * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
-   * made non-enumerable as well.
-   */
-  var hasDontEnumBug = !{ 'valueOf': 0 }.propertyIsEnumerable('valueOf');
+  /** Detect free variable `module` */
+  var freeModule = typeof module == 'object' && module && module.exports == freeExports && module;
+
+  /** Detect free variable `global` and use it as `window` */
+  var freeGlobal = typeof global == 'object' && global;
+  if (freeGlobal.global === freeGlobal) {
+    window = freeGlobal;
+  }
 
   /** Used to generate unique IDs */
   var idCounter = 0;
 
-  /** Used to restore the original `_` reference in `noConflict` */
-  var oldDash = window._;
+  /** Used internally to indicate various things */
+  var indicatorObject = {};
 
-  /** Used to detect if a method is native */
-  var reNative = RegExp('^' + ({}.valueOf + '')
-    .replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&')
-    .replace(/valueOf|for [^\]]+/g, '.+?') + '$');
+  /** 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 tokens in template text */
-  var reToken = /__token__(\d+)/g;
+  /** Used to match HTML entities */
+  var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g;
 
-  /** Used to match unescaped characters in HTML */
-  var reUnescapedHtml = /[&<"']/g;
+  /**
+   * Used to match ES6 template delimiters
+   * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
+   */
+  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
 
-  /** Used to match unescaped characters in compiled string literals */
-  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
+  /** Used to match regexp flags from their coerced string values */
+  var reFlags = /\w*$/;
 
-  /** Used to fix the JScript [[DontEnum]] bug */
-  var shadowed = [
-    'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
-    'toLocaleString', 'toString', 'valueOf'
-  ];
+  /** Used to match "interpolate" template delimiters */
+  var reInterpolate = /<%=([\s\S]+?)%>/g;
 
-  /** Used to make template sourceURLs easier to identify */
-  var templateCounter = 0;
+  /** Used to ensure capturing order of template delimiters */
+  var reNoMatch = /($^)/;
 
-  /** Used to replace template delimiters */
-  var token = '__token__';
+  /** Used to match HTML characters */
+  var reUnescapedHtml = /[&<>"']/g;
 
-  /** Used to store tokenized template text snippets */
-  var tokenized = [];
+  /** Used to match unescaped characters in compiled string literals */
+  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
 
-  /** Detect if sourceURL syntax is usable without erroring */
-  try {
-    // Adobe's and Narwhal's JS engines will error
-    var useSourceURL = (Function('//@')(), true);
-  } catch(e){ }
+  /** Used to make template sourceURLs easier to identify */
+  var templateCounter = 0;
 
-  /**
-   * Used to escape characters for inclusion in HTML.
-   * The `>` and `/` characters don't require escaping in HTML and have no
-   * special meaning unless they're part of a tag or an unquoted attribute value
-   * http://mathiasbynens.be/notes/ambiguous-ampersands (semi-related fun fact)
-   */
-  var htmlEscapes = {
-    '&': '&amp;',
-    '<': '&lt;',
-    '"': '&quot;',
-    "'": '&#x27;'
-  };
+  /** `Object#toString` result shortcuts */
+  var argsClass = '[object Arguments]',
+      arrayClass = '[object Array]',
+      boolClass = '[object Boolean]',
+      dateClass = '[object Date]',
+      funcClass = '[object Function]',
+      numberClass = '[object Number]',
+      objectClass = '[object Object]',
+      regexpClass = '[object RegExp]',
+      stringClass = '[object String]';
 
   /** Used to determine if values are of the language type Object */
   var objectTypes = {
@@ -94,72 +94,142 @@
     '\u2029': 'u2029'
   };
 
-  /** Object#toString result shortcuts */
-  var arrayClass = '[object Array]',
-      boolClass = '[object Boolean]',
-      dateClass = '[object Date]',
-      funcClass = '[object Function]',
-      numberClass = '[object Number]',
-      regexpClass = '[object RegExp]',
-      stringClass = '[object String]';
+  /*--------------------------------------------------------------------------*/
 
-  /** Native prototype shortcuts */
-  var ArrayProto = Array.prototype,
-      ObjectProto = Object.prototype;
+  /** Used for `Array` and `Object` method references */
+  var arrayRef = Array(),
+      objectRef = Object();
 
-  /** Native method shortcuts */
-  var concat = ArrayProto.concat,
-      hasOwnProperty = ObjectProto.hasOwnProperty,
-      push = ArrayProto.push,
-      slice = ArrayProto.slice,
-      toString = ObjectProto.toString;
+  /** Used to restore the original `_` reference in `noConflict` */
+  var oldDash = window._;
+
+  /** Used to detect if a method is native */
+  var reNative = RegExp('^' +
+    String(objectRef.valueOf)
+      .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
+      .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
+  );
 
-  /* Used if `Function#bind` exists and is inferred to be fast (i.e. all but V8) */
-  var nativeBind = reNative.test(nativeBind = slice.bind) &&
-    /\n|Opera/.test(nativeBind + toString.call(window.opera)) && nativeBind;
+  /** Native method shortcuts */
+  var ceil = Math.ceil,
+      clearTimeout = window.clearTimeout,
+      concat = arrayRef.concat,
+      floor = Math.floor,
+      hasOwnProperty = objectRef.hasOwnProperty,
+      push = arrayRef.push,
+      setTimeout = window.setTimeout,
+      slice = arrayRef.slice,
+      toString = objectRef.toString;
 
   /* Native method shortcuts for methods with the same name as other `lodash` methods */
-  var nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
+  var nativeBind = reNative.test(nativeBind = slice.bind) && nativeBind,
+      nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
       nativeIsFinite = window.isFinite,
-      nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys;
+      nativeIsNaN = window.isNaN,
+      nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
+      nativeMax = Math.max,
+      nativeMin = Math.min,
+      nativeRandom = Math.random;
 
-  /** Timer shortcuts */
-  var clearTimeout = window.clearTimeout,
-      setTimeout = window.setTimeout;
+  /** Detect various environments */
+  var isIeOpera = reNative.test(window.attachEvent),
+      isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
 
   /*--------------------------------------------------------------------------*/
 
   /**
-   * The `lodash` function.
+   * Creates a `lodash` object, that wraps the given `value`, to enable method
+   * chaining.
+   *
+   * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
+   * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
+   * and `unshift`
+   *
+   * Chaining is supported in custom builds as long as the `value` method is
+   * implicitly or explicitly included in the build.
+   *
+   * The chainable wrapper functions are:
+   * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
+   * `compose`, `concat`, `countBy`, `createCallback`, `debounce`, `defaults`,
+   * `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`, `forIn`,
+   * `forOwn`, `functions`, `groupBy`, `initial`, `intersection`, `invert`,
+   * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
+   * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
+   * `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
+   * `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `values`,
+   * `where`, `without`, `wrap`, and `zip`
+   *
+   * The non-chainable wrapper functions are:
+   * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
+   * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`,
+   * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`,
+   * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`,
+   * `isUndefined`, `join`, `lastIndexOf`, `mixin`, `noConflict`, `parseInt`,
+   * `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`, `size`, `some`,
+   * `sortedIndex`, `runInContext`, `template`, `unescape`, `uniqueId`, and `value`
+   *
+   * The wrapper functions `first` and `last` return wrapped values when `n` is
+   * passed, otherwise they return unwrapped values.
    *
    * @name _
    * @constructor
-   * @param {Mixed} value The value to wrap in a `LoDash` instance.
-   * @returns {Object} Returns a `LoDash` instance.
+   * @category Chaining
+   * @param {Mixed} value The value to wrap in a `lodash` instance.
+   * @returns {Object} Returns a `lodash` instance.
    */
   function lodash(value) {
-    // allow invoking `lodash` without the `new` operator
-    return new LoDash(value);
+    return (value instanceof lodash)
+      ? value
+      : new lodashWrapper(value);
   }
 
   /**
-   * Creates a `LoDash` instance that wraps a value to allow chaining.
+   * An object used to flag environments features.
    *
-   * @private
-   * @constructor
-   * @param {Mixed} value The value to wrap.
+   * @static
+   * @memberOf _
+   * @type Object
    */
-  function LoDash(value) {
-    // exit early if already wrapped
-    if (value && value._wrapped) {
-      return value;
-    }
-    this._wrapped = value;
-  }
+  var support = {};
+
+  (function() {
+    var object = { '0': 1, 'length': 1 };
+
+    /**
+     * Detect if `arguments` objects are `Object` objects (all but Opera < 10.5).
+     *
+     * @memberOf _.support
+     * @type Boolean
+     */
+    support.argsObject = arguments.constructor == Object;
+
+    /**
+     * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
+     *
+     * @memberOf _.support
+     * @type Boolean
+     */
+    support.fastBind = nativeBind && !isV8;
+
+    /**
+     * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
+     *
+     * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
+     * and `splice()` functions that fail to remove the last element, `value[0]`,
+     * of array-like objects even though the `length` property is set to `0`.
+     * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
+     * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
+     *
+     * @memberOf _.support
+     * @type Boolean
+     */
+    support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
+  }(1));
 
   /**
-   * By default, Lo-Dash uses ERB-style template delimiters, change the
-   * following template settings to use alternative delimiters.
+   * By default, the template delimiters used by Lo-Dash are similar to those in
+   * embedded Ruby (ERB). Change the following template settings to use alternative
+   * delimiters.
    *
    * @static
    * @memberOf _
@@ -170,7 +240,6 @@
     /**
      * Used to detect `data` property values to be HTML-escaped.
      *
-     * @static
      * @memberOf _.templateSettings
      * @type RegExp
      */
@@ -179,7 +248,6 @@
     /**
      * Used to detect code to be evaluated.
      *
-     * @static
      * @memberOf _.templateSettings
      * @type RegExp
      */
@@ -188,279 +256,125 @@
     /**
      * Used to detect `data` property values to inject.
      *
-     * @static
      * @memberOf _.templateSettings
      * @type RegExp
      */
-    'interpolate': /<%=([\s\S]+?)%>/g,
+    'interpolate': reInterpolate,
 
     /**
      * Used to reference the data object in the template text.
      *
-     * @static
      * @memberOf _.templateSettings
      * @type String
      */
-    'variable': 'obj'
+    'variable': ''
   };
 
   /*--------------------------------------------------------------------------*/
 
   /**
-   * The template used to create iterator functions.
+   * Used by `_.max` and `_.min` as the default `callback` when a given
+   * `collection` is a string value.
    *
    * @private
-   * @param {Obect} data The data object used to populate the text.
-   * @returns {String} Returns the interpolated text.
-   */
-  var iteratorTemplate = template(
-    // assign the `result` variable an initial value
-    'var index, result<% if (init) { %> = <%= init %><% } %>;\n' +
-    // add code to exit early or do so if the first argument is falsey
-    '<%= exit %>;\n' +
-    // add code after the exit snippet but before the iteration branches
-    '<%= top %>;\n' +
-
-    // the following branch is for iterating arrays and array-like objects
-    '<% if (arrayBranch) { %>' +
-    'var length = <%= firstArg %>.length; index = -1;' +
-    '  <% if (objectBranch) { %>\nif (length === length >>> 0) {<% } %>\n' +
-    '  <%= arrayBranch.beforeLoop %>;\n' +
-    '  while (<%= arrayBranch.loopExp %>) {\n' +
-    '    <%= arrayBranch.inLoop %>;\n' +
-    '  }' +
-    '  <% if (objectBranch) { %>\n}\n<% }' +
-    '}' +
-
-    // the following branch is for iterating an object's own/inherited properties
-    'if (objectBranch) {' +
-    '  if (arrayBranch) { %>else {\n<% }' +
-    '  if (!hasDontEnumBug) { %>  var skipProto = typeof <%= iteratedObject %> == \'function\';\n<% } %>' +
-    '  <%= objectBranch.beforeLoop %>;\n' +
-    '  for (<%= objectBranch.loopExp %>) {' +
-    '  \n<%' +
-    '  if (hasDontEnumBug) {' +
-    '    if (useHas) { %>    if (<%= hasExp %>) {\n  <% } %>' +
-    '    <%= objectBranch.inLoop %>;<%' +
-    '    if (useHas) { %>\n    }<% }' +
-    '  }' +
-    '  else {' +
-    '  %>' +
-
-    // Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
-    // (if the prototype or a property on the prototype has been set)
-    // incorrectly sets a function's `prototype` property [[Enumerable]]
-    // value to `true`. Because of this Lo-Dash standardizes on skipping
-    // the the `prototype` property of functions regardless of its
-    // [[Enumerable]] value.
-    '    if (!(skipProto && index == \'prototype\')<% if (useHas) { %> && <%= hasExp %><% } %>) {\n' +
-    '      <%= objectBranch.inLoop %>;\n' +
-    '    }' +
-    '  <% } %>\n' +
-    '  }' +
-
-    // Because IE < 9 can't set the `[[Enumerable]]` attribute of an
-    // existing property and the `constructor` property of a prototype
-    // defaults to non-enumerable, Lo-Dash skips the `constructor`
-    // property when it infers it's iterating over a `prototype` object.
-    '  <% if (hasDontEnumBug) { %>\n' +
-    '  var ctor = <%= iteratedObject %>.constructor;\n' +
-    '  <% for (var k = 0; k < 7; k++) { %>\n' +
-    '  index = \'<%= shadowed[k] %>\';\n' +
-    '  if (<%' +
-    '      if (shadowed[k] == \'constructor\') {' +
-    '        %>!(ctor && ctor.prototype === <%= iteratedObject %>) && <%' +
-    '      } %><%= hasExp %>) {\n' +
-    '    <%= objectBranch.inLoop %>;\n' +
-    '  }<%' +
-    '     }' +
-    '   }' +
-    '   if (arrayBranch) { %>\n}<% }' +
-    '} %>\n' +
-
-    // add code to the bottom of the iteration function
-    '<%= bottom %>;\n' +
-    // finally, return the `result`
-    'return result'
-  );
+   * @param {String} value The character to inspect.
+   * @returns {Number} Returns the code unit of given character.
+   */
+  function charAtCallback(value) {
+    return value.charCodeAt(0);
+  }
 
   /**
-   * Reusable iterator options shared by
-   * `every`, `filter`, `find`, `forEach`, `forIn`, `forOwn`, `map`, `reject`, and `some`.
-   */
-  var baseIteratorOptions = {
-    'args': 'collection, callback, thisArg',
-    'init': 'collection',
-    'top':
-      'if (!callback) {\n' +
-      '  callback = identity\n' +
-      '}\n' +
-      'else if (thisArg) {\n' +
-      '  callback = iteratorBind(callback, thisArg)\n' +
-      '}',
-    'inLoop': 'callback(collection[index], index, collection)'
-  };
-
-  /** Reusable iterator options for `every` and `some` */
-  var everyIteratorOptions = {
-    'init': 'true',
-    'inLoop': 'if (!callback(collection[index], index, collection)) return !result'
-  };
-
-  /** Reusable iterator options for `defaults` and `extend` */
-  var extendIteratorOptions = {
-    'args': 'object',
-    'init': 'object',
-    'top':
-      'for (var source, sourceIndex = 1, length = arguments.length; sourceIndex < length; sourceIndex++) {\n' +
-      '  source = arguments[sourceIndex];\n' +
-      (hasDontEnumBug ? '  if (source) {' : ''),
-    'loopExp': 'index in source',
-    'useHas': false,
-    'inLoop': 'object[index] = source[index]',
-    'bottom': (hasDontEnumBug ? '  }\n' : '') + '}'
-  };
-
-  /** Reusable iterator options for `filter` and `reject` */
-  var filterIteratorOptions = {
-    'init': '[]',
-    'inLoop': 'callback(collection[index], index, collection) && result.push(collection[index])'
-  };
+   * Used by `sortBy` to compare transformed `collection` values, stable sorting
+   * them in ascending order.
+   *
+   * @private
+   * @param {Object} a The object to compare to `b`.
+   * @param {Object} b The object to compare to `a`.
+   * @returns {Number} Returns the sort order indicator of `1` or `-1`.
+   */
+  function compareAscending(a, b) {
+    var ai = a.index,
+        bi = b.index;
 
-  /** Reusable iterator options for `find`, `forEach`, `forIn`, and `forOwn` */
-  var forEachIteratorOptions = {
-    'top': 'if (thisArg) callback = iteratorBind(callback, thisArg)'
-  };
+    a = a.criteria;
+    b = b.criteria;
 
-  /** Reusable iterator options for `forIn` and `forOwn` */
-  var forOwnIteratorOptions = {
-    'inLoop': {
-      'object': baseIteratorOptions.inLoop
+    // ensure a stable sort in V8 and other engines
+    // http://code.google.com/p/v8/issues/detail?id=90
+    if (a !== b) {
+      if (a > b || typeof a == 'undefined') {
+        return 1;
+      }
+      if (a < b || typeof b == 'undefined') {
+        return -1;
+      }
     }
-  };
-
-  /*--------------------------------------------------------------------------*/
+    return ai < bi ? -1 : 1;
+  }
 
   /**
-   * Creates compiled iteration functions. The iteration function will be created
-   * to iterate over only objects if the first argument of `options.args` is
-   * "object" or `options.inLoop.array` is falsey.
+   * Creates a function that, when called, invokes `func` with the `this` binding
+   * of `thisArg` and prepends any `partialArgs` to the arguments passed to the
+   * bound function.
    *
    * @private
-   * @param {Object} [options1, options2, ...] The compile options objects.
-   *
-   *  args - A string of comma separated arguments the iteration function will
-   *   accept.
-   *
-   *  init - A string to specify the initial value of the `result` variable.
-   *
-   *  exit - A string of code to use in place of the default exit-early check
-   *   of `if (!arguments[0]) return result`.
-   *
-   *  top - A string of code to execute after the exit-early check but before
-   *   the iteration branches.
-   *
-   *  beforeLoop - A string or object containing an "array" or "object" property
-   *   of code to execute before the array or object loops.
-   *
-   *  loopExp - A string or object containing an "array" or "object" property
-   *   of code to execute as the array or object loop expression.
-   *
-   *  useHas - A boolean to specify whether or not to use `hasOwnProperty` checks
-   *   in the object loop.
-   *
-   *  inLoop - A string or object containing an "array" or "object" property
-   *   of code to execute in the array or object loops.
-   *
-   *  bottom - A string of code to execute after the iteration branches but
-   *   before the `result` is returned.
-   *
-   * @returns {Function} Returns the compiled function.
+   * @param {Function|String} func The function to bind or the method name.
+   * @param {Mixed} [thisArg] The `this` binding of `func`.
+   * @param {Array} partialArgs An array of arguments to be partially applied.
+   * @param {Object} [idicator] Used to indicate binding by key or partially
+   *  applying arguments from the right.
+   * @returns {Function} Returns the new bound function.
    */
-  function createIterator() {
-    var object,
-        prop,
-        value,
-        index = -1,
-        length = arguments.length;
-
-    // merge options into a template data object
-    var data = {
-      'bottom': '',
-      'exit': '',
-      'init': '',
-      'top': '',
-      'arrayBranch': { 'beforeLoop': '', 'loopExp': '++index < length' },
-      'objectBranch': { 'beforeLoop': '' }
-    };
+  function createBound(func, thisArg, partialArgs, indicator) {
+    var isFunc = isFunction(func),
+        isPartial = !partialArgs,
+        key = thisArg;
 
-    while (++index < length) {
-      object = arguments[index];
-      for (prop in object) {
-        value = (value = object[prop]) == null ? '' : value;
-        // keep this regexp explicit for the build pre-process
-        if (/beforeLoop|loopExp|inLoop/.test(prop)) {
-          if (typeof value == 'string') {
-            value = { 'array': value, 'object': value };
-          }
-          data.arrayBranch[prop] = value.array;
-          data.objectBranch[prop] = value.object;
-        } else {
-          data[prop] = value;
-        }
+    // juggle arguments
+    if (isPartial) {
+      var rightIndicator = indicator;
+      partialArgs = thisArg;
+    }
+    else if (!isFunc) {
+      if (!indicator) {
+        throw new TypeError;
       }
+      thisArg = func;
     }
-    // set additional template data values
-    var args = data.args,
-        arrayBranch = data.arrayBranch,
-        objectBranch = data.objectBranch,
-        firstArg = /^[^,]+/.exec(args)[0],
-        loopExp = objectBranch.loopExp,
-        iteratedObject = /\S+$/.exec(loopExp || firstArg)[0];
 
-    data.firstArg = firstArg;
-    data.hasDontEnumBug = hasDontEnumBug;
-    data.hasExp = 'hasOwnProperty.call(' + iteratedObject + ', index)';
-    data.iteratedObject = iteratedObject;
-    data.shadowed = shadowed;
-    data.useHas = data.useHas !== false;
+    function bound() {
+      // `Function#bind` spec
+      // http://es5.github.com/#x15.3.4.5
+      var args = arguments,
+          thisBinding = isPartial ? this : thisArg;
 
-    if (!data.exit) {
-      data.exit = 'if (!' + firstArg + ') return result';
-    }
-    if (firstArg == 'object' || !arrayBranch.inLoop) {
-      data.arrayBranch = null;
-    }
-    if (!loopExp) {
-      objectBranch.loopExp = 'index in ' + iteratedObject;
-    }
-    // create the function factory
-    var factory = Function(
-        'arrayClass, funcClass, hasOwnProperty, identity, iteratorBind, objectTypes, ' +
-        'stringClass, toString, undefined',
-      '"use strict"; return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
-    );
-    // return the compiled function
-    return factory(
-      arrayClass, funcClass, hasOwnProperty, identity, iteratorBind, objectTypes,
-      stringClass, toString
-    );
-  }
+      if (!isFunc) {
+        func = thisArg[key];
+      }
+      if (partialArgs.length) {
+        args = args.length
+          ? (args = slice.call(args), rightIndicator ? args.concat(partialArgs) : partialArgs.concat(args))
+          : partialArgs;
+      }
+      if (this instanceof bound) {
+        // ensure `new bound` is an instance of `func`
+        noop.prototype = func.prototype;
+        thisBinding = new noop;
+        noop.prototype = null;
 
-  /**
-   * Used by `template()` to replace tokens with their corresponding code snippets.
-   *
-   * @private
-   * @param {String} match The matched token.
-   * @param {String} index The `tokenized` index of the code snippet.
-   * @returns {String} Returns the code snippet.
-   */
-  function detokenize(match, index) {
-    return tokenized[index];
+        // mimic the constructor's `return` behavior
+        // http://es5.github.com/#x13.2.2
+        var result = func.apply(thisBinding, args);
+        return isObject(result) ? result : thisBinding;
+      }
+      return func.apply(thisBinding, args);
+    }
+    return bound;
   }
 
   /**
-   * Used by `template()` to escape characters for inclusion in compiled
+   * Used by `template` to escape characters for inclusion in compiled
    * string literals.
    *
    * @private
@@ -472,7 +386,7 @@
   }
 
   /**
-   * Used by `escape()` to escape characters for inclusion in HTML.
+   * Used by `escape` to convert characters to HTML entities.
    *
    * @private
    * @param {String} match The matched character to escape.
@@ -483,19 +397,17 @@
   }
 
   /**
-   * Creates a new function that, when called, invokes `func` with the `this`
-   * binding of `thisArg` and the arguments (value, index, object).
+   * A fast path for creating `lodash` wrapper objects.
    *
    * @private
-   * @param {Function} func The function to bind.
-   * @param {Mixed} [thisArg] The `this` binding of `func`.
-   * @returns {Function} Returns the new bound function.
+   * @param {Mixed} value The value to wrap in a `lodash` instance.
+   * @returns {Object} Returns a `lodash` instance.
    */
-  function iteratorBind(func, thisArg) {
-    return function(value, index, object) {
-      return func.call(thisArg, value, index, object);
-    };
+  function lodashWrapper(value) {
+    this.__wrapped__ = value;
   }
+  // ensure `new lodashWrapper` is an instance of `lodash`
+  lodashWrapper.prototype = lodash.prototype;
 
   /**
    * A no-operation function.
@@ -507,2484 +419,3264 @@
   }
 
   /**
-   * A shim implementation of `Object.keys` that produces an array of the given
-   * object's own enumerable property names.
-   *
-   * @private
-   * @param {Object} object The object to inspect.
-   * @returns {Array} Returns a new array of property names.
-   */
-  var shimKeys = createIterator({
-    'args': 'object',
-    'exit': 'if (!objectTypes[typeof object] || object === null) throw TypeError()',
-    'init': '[]',
-    'inLoop': 'result.push(index)'
-  });
-
-  /**
-   * Used by `template()` to replace "escape" template delimiters with tokens.
-   *
-   * @private
-   * @param {String} match The matched template delimiter.
-   * @param {String} value The delimiter value.
-   * @returns {String} Returns a token.
-   */
-  function tokenizeEscape(match, value) {
-    var index = tokenized.length;
-    tokenized[index] = "'+\n_.escape(" + value + ") +\n'";
-    return token + index;
-  }
-
-  /**
-   * Used by `template()` to replace "interpolate" template delimiters with tokens.
-   *
-   * @private
-   * @param {String} match The matched template delimiter.
-   * @param {String} value The delimiter value.
-   * @returns {String} Returns a token.
-   */
-  function tokenizeInterpolate(match, value) {
-    var index = tokenized.length;
-    tokenized[index] = "'+\n((__t = (" + value + ")) == null ? '' : __t) +\n'";
-    return token + index;
-  }
-
-  /**
-   * Used by `template()` to replace "evaluate" template delimiters with tokens.
+   * Used by `unescape` to convert HTML entities to characters.
    *
    * @private
-   * @param {String} match The matched template delimiter.
-   * @param {String} value The delimiter value.
-   * @returns {String} Returns a token.
+   * @param {String} match The matched character to unescape.
+   * @returns {String} Returns the unescaped character.
    */
-  function tokenizeEvaluate(match, value) {
-    var index = tokenized.length;
-    tokenized[index] = "';\n" + value + ";\n__p += '";
-    return token + index;
+  function unescapeHtmlChar(match) {
+    return htmlUnescapes[match];
   }
 
   /*--------------------------------------------------------------------------*/
 
   /**
-   * Checks if a given `target` value is present in a `collection` using strict
-   * equality for comparisons, i.e. `===`.
+   * Checks if `value` is an `arguments` object.
    *
    * @static
    * @memberOf _
-   * @alias include
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Mixed} target The value to check for.
-   * @returns {Boolean} Returns `true` if `target` value is found, else `false`.
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is an `arguments` object, else `false`.
    * @example
    *
-   * _.contains([1, 2, 3], 3);
+   * (function() { return _.isArguments(arguments); })(1, 2, 3);
    * // => true
+   *
+   * _.isArguments([1, 2, 3]);
+   * // => false
    */
-  var contains = createIterator({
-    'args': 'collection, target',
-    'init': 'false',
-    'inLoop': 'if (collection[index] === target) return true'
-  });
+  function isArguments(value) {
+    return toString.call(value) == argsClass;
+  }
+  // fallback for browsers that can't detect `arguments` objects by [[Class]]
+  if (!isArguments(arguments)) {
+    isArguments = function(value) {
+      return value ? hasOwnProperty.call(value, 'callee') : false;
+    };
+  }
 
   /**
-   * Checks if the `callback` returns a truthy value for **all** elements of a
-   * `collection`. The `callback` is bound to `thisArg` and invoked with 3
-   * arguments; for arrays they are (value, index, array) and for objects they
-   * are (value, key, object).
+   * Checks if `value` is an array.
    *
    * @static
    * @memberOf _
-   * @alias all
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} [callback=identity] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Boolean} Returns `true` if all values pass the callback check, else `false`.
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is an array, else `false`.
    * @example
    *
-   * _.every([true, 1, null, 'yes'], Boolean);
+   * (function() { return _.isArray(arguments); })();
    * // => false
+   *
+   * _.isArray([1, 2, 3]);
+   * // => true
    */
-  var every = createIterator(baseIteratorOptions, everyIteratorOptions);
+  var isArray = nativeIsArray || function(value) {
+    // `instanceof` may cause a memory leak in IE 7 if `value` is a host object
+    // http://ajaxian.com/archives/working-aroung-the-instanceof-memory-leak
+    return (support.argsObject && value instanceof Array) || toString.call(value) == arrayClass;
+  };
 
   /**
-   * Examines each value in a `collection`, returning an array of all values the
-   * `callback` returns truthy for. The `callback` is bound to `thisArg` and
-   * invoked with 3 arguments; for arrays they are (value, index, array) and for
-   * objects they are (value, key, object).
-   *
-   * @static
-   * @memberOf _
-   * @alias select
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} [callback=identity] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Array} Returns a new array of values that passed callback check.
-   * @example
+   * A fallback implementation of `Object.keys` that produces an array of the
+   * given object's own enumerable property names.
    *
-   * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-   * // => [2, 4, 6]
+   * @private
+   * @type Function
+   * @param {Object} object The object to inspect.
+   * @returns {Array} Returns a new array of property names.
    */
-  var filter = createIterator(baseIteratorOptions, filterIteratorOptions);
+  var shimKeys = function (object) {
+    var index, iterable = object, result = [];
+    if (!iterable) return result;
+    if (!(objectTypes[typeof object])) return result;
+
+      for (index in iterable) {
+        if (hasOwnProperty.call(iterable, index)) {    
+        result.push(index);    
+        }
+      }  
+    return result
+  };
 
   /**
-   * Examines each value in a `collection`, returning the first one the `callback`
-   * returns truthy for. The function returns as soon as it finds an acceptable
-   * value, and does not iterate over the entire `collection`. The `callback` is
-   * bound to `thisArg` and invoked with 3 arguments; for arrays they are
-   * (value, index, array) and for objects they are (value, key, object).
+   * Creates an array composed of the own enumerable property names of `object`.
    *
    * @static
    * @memberOf _
-   * @alias detect
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} callback The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Mixed} Returns the value that passed the callback check, else `undefined`.
+   * @category Objects
+   * @param {Object} object The object to inspect.
+   * @returns {Array} Returns a new array of property names.
    * @example
    *
-   * var even = _.find([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-   * // => 2
+   * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
+   * // => ['one', 'two', 'three'] (order is not guaranteed)
    */
-  var find = createIterator(baseIteratorOptions, forEachIteratorOptions, {
-    'init': '',
-    'inLoop': 'if (callback(collection[index], index, collection)) return collection[index]'
-  });
+  var keys = !nativeKeys ? shimKeys : function(object) {
+    if (!isObject(object)) {
+      return [];
+    }
+    return nativeKeys(object);
+  };
 
   /**
-   * Iterates over a `collection`, executing the `callback` for each value in the
-   * `collection`. The `callback` is bound to `thisArg` and invoked with 3
-   * arguments; for arrays they are (value, index, array) and for objects they
-   * are (value, key, object).
-   *
-   * @static
-   * @memberOf _
-   * @alias each
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} callback The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Array|Object} Returns the `collection`.
-   * @example
-   *
-   * _([1, 2, 3]).forEach(alert).join(',');
-   * // => alerts each number and returns '1,2,3'
+   * Used to convert characters to HTML entities:
    *
-   * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, alert);
-   * // => alerts each number (order is not guaranteed)
+   * Though the `>` character is escaped for symmetry, characters like `>` and `/`
+   * don't require escaping in HTML and have no special meaning unless they're part
+   * of a tag or an unquoted attribute value.
+   * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
    */
-  var forEach = createIterator(baseIteratorOptions, forEachIteratorOptions);
+  var htmlEscapes = {
+    '&': '&amp;',
+    '<': '&lt;',
+    '>': '&gt;',
+    '"': '&quot;',
+    "'": '&#39;'
+  };
+
+  /** Used to convert HTML entities to characters */
+  var htmlUnescapes = invert(htmlEscapes);
+
+  /*--------------------------------------------------------------------------*/
 
   /**
-   * Produces a new array of values by mapping each value in the `collection`
-   * through a transformation `callback`. The `callback` is bound to `thisArg`
-   * and invoked with 3 arguments; for arrays they are (value, index, array)
-   * and for objects they are (value, key, object).
+   * Assigns own enumerable properties of source object(s) to the destination
+   * object. Subsequent sources will overwrite property assignments of previous
+   * sources. If a `callback` function is passed, it will be executed to produce
+   * the assigned values. The `callback` is bound to `thisArg` and invoked with
+   * two arguments; (objectValue, sourceValue).
    *
    * @static
    * @memberOf _
-   * @alias collect
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} [callback=identity] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Array} Returns a new array of values returned by the callback.
+   * @type Function
+   * @alias extend
+   * @category Objects
+   * @param {Object} object The destination object.
+   * @param {Object} [source1, source2, ...] The source objects.
+   * @param {Function} [callback] The function to customize assigning values.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Object} Returns the destination object.
    * @example
    *
-   * _.map([1, 2, 3], function(num) { return num * 3; });
-   * // => [3, 6, 9]
+   * _.assign({ 'name': 'moe' }, { 'age': 40 });
+   * // => { 'name': 'moe', 'age': 40 }
    *
-   * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
-   * // => [3, 6, 9] (order is not guaranteed)
+   * var defaults = _.partialRight(_.assign, function(a, b) {
+   *   return typeof a == 'undefined' ? b : a;
+   * });
+   *
+   * var food = { 'name': 'apple' };
+   * defaults(food, { 'name': 'banana', 'type': 'fruit' });
+   * // => { 'name': 'apple', 'type': 'fruit' }
    */
-  var map = createIterator(baseIteratorOptions, {
-    'init': '',
-    'exit': 'if (!collection) return []',
-    'beforeLoop': {
-      'array':  'result = Array(length)',
-      'object': 'result = []'
-    },
-    'inLoop': {
-      'array':  'result[index] = callback(collection[index], index, collection)',
-      'object': 'result.push(callback(collection[index], index, collection))'
+  function assign(object) {
+    if (!object) {
+      return object;
     }
-  });
-
-  /**
-   * Boils down a `collection` to a single value. The initial state of the
-   * reduction is `accumulator` and each successive step of it should be returned
-   * by the `callback`. The `callback` is bound to `thisArg` and invoked with 4
-   * arguments; for arrays they are (accumulator, value, index, array) and for
-   * objects they are (accumulator, value, key, object).
+    for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
+      var iterable = arguments[argsIndex];
+      if (iterable) {
+        for (var key in iterable) {
+          object[key] = iterable[key];
+        }
+      }
+    }
+    return object;
+  }
+
+  /**
+   * Creates a clone of `value`. If `deep` is `true`, nested objects will also
+   * be cloned, otherwise they will be assigned by reference. If a `callback`
+   * function is passed, it will be executed to produce the cloned values. If
+   * `callback` returns `undefined`, cloning will be handled by the method instead.
+   * The `callback` is bound to `thisArg` and invoked with one argument; (value).
    *
    * @static
    * @memberOf _
-   * @alias foldl, inject
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} callback The function called per iteration.
-   * @param {Mixed} [accumulator] Initial value of the accumulator.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Mixed} Returns the accumulated value.
+   * @category Objects
+   * @param {Mixed} value The value to clone.
+   * @param {Boolean} [deep=false] A flag to indicate a deep clone.
+   * @param {Function} [callback] The function to customize cloning values.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @param- {Array} [stackA=[]] Tracks traversed source objects.
+   * @param- {Array} [stackB=[]] Associates clones with source counterparts.
+   * @returns {Mixed} Returns the cloned `value`.
    * @example
    *
-   * var sum = _.reduce([1, 2, 3], function(memo, num) { return memo + num; });
-   * // => 6
+   * var stooges = [
+   *   { 'name': 'moe', 'age': 40 },
+   *   { 'name': 'larry', 'age': 50 }
+   * ];
+   *
+   * var shallow = _.clone(stooges);
+   * shallow[0] === stooges[0];
+   * // => true
+   *
+   * var deep = _.clone(stooges, true);
+   * deep[0] === stooges[0];
+   * // => false
+   *
+   * _.mixin({
+   *   'clone': _.partialRight(_.clone, function(value) {
+   *     return _.isElement(value) ? value.cloneNode(false) : undefined;
+   *   })
+   * });
+   *
+   * var clone = _.clone(document.body);
+   * clone.childNodes.length;
+   * // => 0
    */
-  var reduce = createIterator({
-    'args': 'collection, callback, accumulator, thisArg',
-    'init': 'accumulator',
-    'top':
-      'var noaccum = arguments.length < 3;\n' +
-      'if (thisArg) callback = iteratorBind(callback, thisArg)',
-    'beforeLoop': {
-      'array': 'if (noaccum) result = collection[++index]'
-    },
-    'inLoop': {
-      'array':
-        'result = callback(result, collection[index], index, collection)',
-      'object':
-        'result = noaccum\n' +
-        '  ? (noaccum = false, collection[index])\n' +
-        '  : callback(result, collection[index], index, collection)'
-    }
-  });
+  function clone(value) {
+    return isObject(value)
+      ? (isArray(value) ? slice.call(value) : assign({}, value))
+      : value;
+  }
 
   /**
-   * The right-associative version of `_.reduce`.
+   * Assigns own enumerable properties of source object(s) to the destination
+   * object for all destination properties that resolve to `undefined`. Once a
+   * property is set, additional defaults of the same property will be ignored.
    *
    * @static
    * @memberOf _
-   * @alias foldr
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
-   * @param {Function} callback The function called per iteration.
-   * @param {Mixed} [accumulator] Initial value of the accumulator.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Mixed} Returns the accumulated value.
+   * @type Function
+   * @category Objects
+   * @param {Object} object The destination object.
+   * @param {Object} [source1, source2, ...] The source objects.
+   * @param- {Object} [guard] Allows working with `_.reduce` without using its
+   *  callback's `key` and `object` arguments as sources.
+   * @returns {Object} Returns the destination object.
    * @example
    *
-   * var list = [[0, 1], [2, 3], [4, 5]];
-   * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
-   * // => [4, 5, 2, 3, 0, 1]
+   * var food = { 'name': 'apple' };
+   * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
+   * // => { 'name': 'apple', 'type': 'fruit' }
    */
-  function reduceRight(collection, callback, accumulator, thisArg) {
-    if (!collection) {
-      return accumulator;
-    }
-
-    var length = collection.length,
-        noaccum = arguments.length < 3;
-
-    if(thisArg) {
-      callback = iteratorBind(callback, thisArg);
+  function defaults(object) {
+    if (!object) {
+      return object;
     }
-    if (length === length >>> 0) {
-      if (length && noaccum) {
-        accumulator = collection[--length];
-      }
-      while (length--) {
-        accumulator = callback(accumulator, collection[length], length, collection);
+    for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
+      var iterable = arguments[argsIndex];
+      if (iterable) {
+        for (var key in iterable) {
+          if (object[key] == null) {
+            object[key] = iterable[key];
+          }
+        }
       }
-      return accumulator;
-    }
-
-    var prop,
-        props = keys(collection);
-
-    length = props.length;
-    if (length && noaccum) {
-      accumulator = collection[props[--length]];
-    }
-    while (length--) {
-      prop = props[length];
-      accumulator = callback(accumulator, collection[prop], prop, collection);
     }
-    return accumulator;
+    return object;
   }
 
   /**
-   * The opposite of `_.filter`, this method returns the values of a `collection`
-   * that `callback` does **not** return truthy for.
+   * Iterates over `object`'s own and inherited enumerable properties, executing
+   * the `callback` for each property. The `callback` is bound to `thisArg` and
+   * invoked with three arguments; (value, key, object). Callbacks may exit iteration
+   * early by explicitly returning `false`.
    *
    * @static
    * @memberOf _
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
+   * @type Function
+   * @category Objects
+   * @param {Object} object The object to iterate over.
    * @param {Function} [callback=identity] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Array} Returns a new array of values that did **not** pass the callback check.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Object} Returns `object`.
    * @example
    *
-   * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
-   * // => [1, 3, 5]
+   * function Dog(name) {
+   *   this.name = name;
+   * }
+   *
+   * Dog.prototype.bark = function() {
+   *   alert('Woof, woof!');
+   * };
+   *
+   * _.forIn(new Dog('Dagny'), function(value, key) {
+   *   alert(key);
+   * });
+   * // => alerts 'name' and 'bark' (order is not guaranteed)
    */
-  var reject = createIterator(baseIteratorOptions, filterIteratorOptions, {
-    'inLoop': '!' + filterIteratorOptions.inLoop
-  });
+  var forIn = function (collection, callback) {
+    var index, iterable = collection, result = iterable;
+    if (!iterable) return result;
+    if (!objectTypes[typeof iterable]) return result;
+
+      for (index in iterable) {
+        if (callback(iterable[index], index, collection) === indicatorObject) return result;    
+      }  
+    return result
+  };
 
   /**
-   * Checks if the `callback` returns a truthy value for **any** element of a
-   * `collection`. The function returns as soon as it finds passing value, and
-   * does not iterate over the entire `collection`. The `callback` is bound to
-   * `thisArg` and invoked with 3 arguments; for arrays they are
-   * (value, index, array) and for objects they are (value, key, object).
+   * Iterates over an object's own enumerable properties, executing the `callback`
+   * for each property. The `callback` is bound to `thisArg` and invoked with three
+   * arguments; (value, key, object). Callbacks may exit iteration early by explicitly
+   * returning `false`.
    *
    * @static
    * @memberOf _
-   * @alias any
-   * @category Collections
-   * @param {Array|Object} collection The collection to iterate over.
+   * @type Function
+   * @category Objects
+   * @param {Object} object The object to iterate over.
    * @param {Function} [callback=identity] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Boolean} Returns `true` if any value passes the callback check, else `false`.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Object} Returns `object`.
    * @example
    *
-   * _.some([null, 0, 'yes', false]);
-   * // => true
+   * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
+   *   alert(key);
+   * });
+   * // => alerts '0', '1', and 'length' (order is not guaranteed)
    */
-  var some = createIterator(baseIteratorOptions, everyIteratorOptions, {
-    'init': 'false',
-    'inLoop': everyIteratorOptions.inLoop.replace('!', '')
-  });
+  var forOwn = function (collection, callback) {
+    var index, iterable = collection, result = iterable;
+    if (!iterable) return result;
+    if (!objectTypes[typeof iterable]) return result;
+
+      for (index in iterable) {
+        if (hasOwnProperty.call(iterable, index)) {    
+        if (callback(iterable[index], index, collection) === indicatorObject) return result;    
+        }
+      }  
+    return result
+  };
 
   /**
-   * Converts the `collection`, into an array. Useful for converting the
-   * `arguments` object.
+   * Creates a sorted array of all enumerable properties, own and inherited,
+   * of `object` that have function values.
    *
    * @static
    * @memberOf _
-   * @category Collections
-   * @param {Array|Object} collection The collection to convert.
-   * @returns {Array} Returns the new converted array.
+   * @alias methods
+   * @category Objects
+   * @param {Object} object The object to inspect.
+   * @returns {Array} Returns a new array of property names that have function values.
    * @example
    *
-   * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
-   * // => [2, 3, 4]
+   * _.functions(_);
+   * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
    */
-  function toArray(collection) {
-    if (!collection) {
-      return [];
-    }
-    if (toString.call(collection.toArray) == funcClass) {
-      return collection.toArray();
-    }
-    var length = collection.length;
-    if (length === length >>> 0) {
-      return slice.call(collection);
-    }
-    return values(collection);
+  function functions(object) {
+    var result = [];
+    forIn(object, function(value, key) {
+      if (isFunction(value)) {
+        result.push(key);
+      }
+    });
+    return result.sort();
   }
 
-  /*--------------------------------------------------------------------------*/
-
   /**
-   * Produces a new array with all falsey values of `array` removed. The values
-   * `false`, `null`, `0`, `""`, `undefined` and `NaN` are all falsey.
+   * Checks if the specified object `property` exists and is a direct property,
+   * instead of an inherited property.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to compact.
-   * @returns {Array} Returns a new filtered array.
+   * @category Objects
+   * @param {Object} object The object to check.
+   * @param {String} property The property to check for.
+   * @returns {Boolean} Returns `true` if key is a direct property, else `false`.
    * @example
    *
-   * _.compact([0, 1, false, 2, '', 3]);
-   * // => [1, 2, 3]
+   * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
+   * // => true
    */
-  function compact(array) {
-    var result = [];
-    if (!array) {
-      return result;
-    }
-    var index = -1,
-        length = array.length;
-
-    while (++index < length) {
-      if (array[index]) {
-        result.push(array[index]);
-      }
-    }
-    return result;
+  function has(object, property) {
+    return object ? hasOwnProperty.call(object, property) : false;
   }
 
   /**
-   * Produces a new array of `array` values not present in the other arrays
-   * using strict equality for comparisons, i.e. `===`.
+   * Creates an object composed of the inverted keys and values of the given `object`.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to process.
-   * @param {Array} [array1, array2, ...] Arrays to check.
-   * @returns {Array} Returns a new array of `array` values not present in the
-   *  other arrays.
+   * @category Objects
+   * @param {Object} object The object to invert.
+   * @returns {Object} Returns the created inverted object.
    * @example
    *
-   * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
-   * // => [1, 3, 4]
+   *  _.invert({ 'first': 'moe', 'second': 'larry' });
+   * // => { 'moe': 'first', 'larry': 'second' }
    */
-  function difference(array) {
-    var result = [];
-    if (!array) {
-      return result;
-    }
+  function invert(object) {
     var index = -1,
-        length = array.length,
-        flattened = concat.apply(result, slice.call(arguments, 1));
+        props = keys(object),
+        length = props.length,
+        result = {};
 
     while (++index < length) {
-      if (indexOf(flattened, array[index]) < 0) {
-        result.push(array[index]);
-      }
+      var key = props[index];
+      result[object[key]] = key;
     }
     return result;
   }
 
   /**
-   * Gets the first value of the `array`. Pass `n` to return the first `n` values
-   * of the `array`.
+   * Checks if `value` is a boolean value.
    *
    * @static
    * @memberOf _
-   * @alias head, take
-   * @category Arrays
-   * @param {Array} array The array to query.
-   * @param {Number} [n] The number of elements to return.
-   * @param {Object} [guard] Internally used to allow this method to work with
-   *  others like `_.map` without using their callback `index` argument for `n`.
-   * @returns {Mixed} Returns the first value or an array of the first `n` values
-   *  of `array`.
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a boolean value, else `false`.
    * @example
    *
-   * _.first([5, 4, 3, 2, 1]);
-   * // => 5
+   * _.isBoolean(null);
+   * // => false
    */
-  function first(array, n, guard) {
-    if (array) {
-      return (n == undefined || guard) ? array[0] : slice.call(array, 0, n);
-    }
+  function isBoolean(value) {
+    return value === true || value === false || toString.call(value) == boolClass;
   }
 
   /**
-   * Flattens a nested array (the nesting can be to any depth). If `shallow` is
-   * truthy, `array` will only be flattened a single level.
+   * Checks if `value` is a date.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to compact.
-   * @param {Boolean} shallow A flag to indicate only flattening a single level.
-   * @returns {Array} Returns a new flattened array.
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a date, else `false`.
    * @example
    *
-   * _.flatten([1, [2], [3, [[4]]]]);
-   * // => [1, 2, 3, 4];
-   *
-   * _.flatten([1, [2], [3, [[4]]]], true);
-   * // => [1, 2, 3, [[4]]];
+   * _.isDate(new Date);
+   * // => true
    */
-  function flatten(array, shallow) {
-    var result = [];
-    if (!array) {
-      return result;
-    }
-    var value,
-        index = -1,
-        length = array.length;
+  function isDate(value) {
+    return value instanceof Date || toString.call(value) == dateClass;
+  }
 
-    while (++index < length) {
-      value = array[index];
-      if (isArray(value)) {
-        push.apply(result, shallow ? value : flatten(value));
-      } else {
-        result.push(value);
-      }
-    }
-    return result;
+  /**
+   * Checks if `value` is a DOM element.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a DOM element, else `false`.
+   * @example
+   *
+   * _.isElement(document.body);
+   * // => true
+   */
+  function isElement(value) {
+    return value ? value.nodeType === 1 : false;
   }
 
   /**
-   * Splits `array` into sets, grouped by the result of running each value
-   * through `callback`. The `callback` is bound to `thisArg` and invoked with 3
-   * arguments; (value, index, array). The `callback` argument may also be the
-   * name of a property to group by.
+   * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
+   * length of `0` and objects with no own enumerable properties are considered
+   * "empty".
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to iterate over.
-   * @param {Function|String} callback The function called per iteration or
-   *  property name to group by.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Object} Returns an object of grouped values.
+   * @category Objects
+   * @param {Array|Object|String} value The value to inspect.
+   * @returns {Boolean} Returns `true`, if the `value` is empty, else `false`.
    * @example
    *
-   * _.groupBy([1.3, 2.1, 2.4], function(num) { return Math.floor(num); });
-   * // => { '1': [1.3], '2': [2.1, 2.4] }
+   * _.isEmpty([1, 2, 3]);
+   * // => false
    *
-   * _.groupBy([1.3, 2.1, 2.4], function(num) { return this.floor(num); }, Math);
-   * // => { '1': [1.3], '2': [2.1, 2.4] }
+   * _.isEmpty({});
+   * // => true
    *
-   * _.groupBy(['one', 'two', 'three'], 'length');
-   * // => { '3': ['one', 'two'], '5': ['three'] }
+   * _.isEmpty('');
+   * // => true
    */
-  function groupBy(array, callback, thisArg) {
-    var result = {};
-    if (!array) {
-      return result;
+  function isEmpty(value) {
+    if (!value) {
+      return true;
     }
-    var prop,
-        value,
-        index = -1,
-        isFunc = typeof callback == 'function',
-        length = array.length;
-
-    if (isFunc && thisArg) {
-      callback = iteratorBind(callback, thisArg);
+    if (isArray(value) || isString(value)) {
+      return !value.length;
     }
-    while (++index < length) {
-      value = array[index];
-      prop = isFunc ? callback(value, index, array) : value[callback];
-      (hasOwnProperty.call(result, prop) ? result[prop] : result[prop] = []).push(value);
+    for (var key in value) {
+      if (hasOwnProperty.call(value, key)) {
+        return false;
+      }
     }
-    return result;
+    return true;
   }
 
   /**
-   * Gets the index at which the first occurrence of `value` is found using
-   * strict equality for comparisons, i.e. `===`. If the `array` is already
-   * sorted, passing `true` for `isSorted` will run a faster binary search.
+   * Performs a deep comparison between two values to determine if they are
+   * equivalent to each other. If `callback` is passed, it will be executed to
+   * compare values. If `callback` returns `undefined`, comparisons will be handled
+   * by the method instead. The `callback` is bound to `thisArg` and invoked with
+   * two arguments; (a, b).
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to search.
-   * @param {Mixed} value The value to search for.
-   * @param {Boolean|Number} [fromIndex=0] The index to start searching from or
-   *  `true` to perform a binary search on a sorted `array`.
-   * @returns {Number} Returns the index of the matched value or `-1`.
+   * @category Objects
+   * @param {Mixed} a The value to compare.
+   * @param {Mixed} b The other value to compare.
+   * @param {Function} [callback] The function to customize comparing values.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @param- {Array} [stackA=[]] Tracks traversed `a` objects.
+   * @param- {Array} [stackB=[]] Tracks traversed `b` objects.
+   * @returns {Boolean} Returns `true`, if the values are equivalent, else `false`.
    * @example
    *
-   * _.indexOf([1, 2, 3, 1, 2, 3], 2);
-   * // => 1
+   * var moe = { 'name': 'moe', 'age': 40 };
+   * var copy = { 'name': 'moe', 'age': 40 };
    *
-   * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
-   * // => 4
+   * moe == copy;
+   * // => false
    *
-   * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
-   * // => 2
-   */
-  function indexOf(array, value, fromIndex) {
-    if (!array) {
-      return -1;
+   * _.isEqual(moe, copy);
+   * // => true
+   *
+   * var words = ['hello', 'goodbye'];
+   * var otherWords = ['hi', 'goodbye'];
+   *
+   * _.isEqual(words, otherWords, function(a, b) {
+   *   var reGreet = /^(?:hello|hi)$/i,
+   *       aGreet = _.isString(a) && reGreet.test(a),
+   *       bGreet = _.isString(b) && reGreet.test(b);
+   *
+   *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
+   * });
+   * // => true
+   */
+  function isEqual(a, b, stackA, stackB) {
+    if (a === b) {
+      return a !== 0 || (1 / a == 1 / b);
     }
-    var index = -1,
-        length = array.length;
+    var type = typeof a,
+        otherType = typeof b;
 
-    if (fromIndex) {
-      if (typeof fromIndex == 'number') {
-        index = (fromIndex < 0 ? Math.max(0, length + fromIndex) : fromIndex) - 1;
-      } else {
-        index = sortedIndex(array, value);
-        return array[index] === value ? index : -1;
+    if (a === a &&
+        (!a || (type != 'function' && type != 'object')) &&
+        (!b || (otherType != 'function' && otherType != 'object'))) {
+      return false;
+    }
+    if (a == null || b == null) {
+      return a === b;
+    }
+    var className = toString.call(a),
+        otherClass = toString.call(b);
+
+    if (className != otherClass) {
+      return false;
+    }
+    switch (className) {
+      case boolClass:
+      case dateClass:
+        return +a == +b;
+
+      case numberClass:
+        return a != +a
+          ? b != +b
+          : (a == 0 ? (1 / a == 1 / b) : a == +b);
+
+      case regexpClass:
+      case stringClass:
+        return a == String(b);
+    }
+    var isArr = className == arrayClass;
+    if (!isArr) {
+      if (a instanceof lodash || b instanceof lodash) {
+        return isEqual(a.__wrapped__ || a, b.__wrapped__ || b, stackA, stackB);
+      }
+      if (className != objectClass) {
+        return false;
+      }
+      var ctorA = a.constructor,
+          ctorB = b.constructor;
+
+      if (ctorA != ctorB && !(
+            isFunction(ctorA) && ctorA instanceof ctorA &&
+            isFunction(ctorB) && ctorB instanceof ctorB
+          )) {
+        return false;
       }
     }
-    while (++index < length) {
-      if (array[index] === value) {
-        return index;
+    stackA || (stackA = []);
+    stackB || (stackB = []);
+
+    var length = stackA.length;
+    while (length--) {
+      if (stackA[length] == a) {
+        return stackB[length] == b;
       }
     }
-    return -1;
+    var result = true,
+        size = 0;
+
+    stackA.push(a);
+    stackB.push(b);
+
+    if (isArr) {
+      size = b.length;
+      result = size == a.length;
+
+      if (result) {
+        while (size--) {
+          if (!(result = isEqual(a[size], b[size], stackA, stackB))) {
+            break;
+          }
+        }
+      }
+      return result;
+    }
+    forIn(b, function(value, key, b) {
+      if (hasOwnProperty.call(b, key)) {
+        size++;
+        return !(result = hasOwnProperty.call(a, key) && isEqual(a[key], value, stackA, stackB)) && indicatorObject;
+      }
+    });
+
+    if (result) {
+      forIn(a, function(value, key, a) {
+        if (hasOwnProperty.call(a, key)) {
+          return !(result = --size > -1) && indicatorObject;
+        }
+      });
+    }
+    return result;
   }
 
   /**
-   * Gets all but the last value of `array`. Pass `n` to exclude the last `n`
-   * values from the result.
+   * Checks if `value` is, or can be coerced to, a finite number.
+   *
+   * Note: This is not the same as native `isFinite`, which will return true for
+   * booleans and empty strings. See http://es5.github.com/#x15.1.2.5.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to query.
-   * @param {Number} [n] The number of elements to return.
-   * @param {Object} [guard] Internally used to allow this method to work with
-   *  others like `_.map` without using their callback `index` argument for `n`.
-   * @returns {Array} Returns all but the last value or `n` values of `array`.
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is finite, else `false`.
+   * @example
+   *
+   * _.isFinite(-101);
+   * // => true
+   *
+   * _.isFinite('10');
+   * // => true
+   *
+   * _.isFinite(true);
+   * // => false
+   *
+   * _.isFinite('');
+   * // => false
+   *
+   * _.isFinite(Infinity);
+   * // => false
+   */
+  function isFinite(value) {
+    return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
+  }
+
+  /**
+   * Checks if `value` is a function.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a function, else `false`.
    * @example
    *
-   * _.initial([3, 2, 1]);
-   * // => [3, 2]
+   * _.isFunction(_);
+   * // => true
    */
-  function initial(array, n, guard) {
-    if (!array) {
-      return [];
+  function isFunction(value) {
+    return typeof value == 'function';
+  }
+  // fallback for older versions of Chrome and Safari
+  if (isFunction(/x/)) {
+    isFunction = function(value) {
+      return value instanceof Function || toString.call(value) == funcClass;
+    };
+  }
+
+  /**
+   * Checks if `value` is the language type of Object.
+   * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is an object, else `false`.
+   * @example
+   *
+   * _.isObject({});
+   * // => true
+   *
+   * _.isObject([1, 2, 3]);
+   * // => true
+   *
+   * _.isObject(1);
+   * // => false
+   */
+  function isObject(value) {
+    // check if the value is the ECMAScript language type of Object
+    // http://es5.github.com/#x8
+    // and avoid a V8 bug
+    // http://code.google.com/p/v8/issues/detail?id=2291
+    return value ? objectTypes[typeof value] : false;
+  }
+
+  /**
+   * Checks if `value` is `NaN`.
+   *
+   * Note: This is not the same as native `isNaN`, which will return `true` for
+   * `undefined` and other values. See http://es5.github.com/#x15.1.2.4.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is `NaN`, else `false`.
+   * @example
+   *
+   * _.isNaN(NaN);
+   * // => true
+   *
+   * _.isNaN(new Number(NaN));
+   * // => true
+   *
+   * isNaN(undefined);
+   * // => true
+   *
+   * _.isNaN(undefined);
+   * // => false
+   */
+  function isNaN(value) {
+    // `NaN` as a primitive is the only value that is not equal to itself
+    // (perform the [[Class]] check first to avoid errors with some host objects in IE)
+    return isNumber(value) && value != +value
+  }
+
+  /**
+   * Checks if `value` is `null`.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is `null`, else `false`.
+   * @example
+   *
+   * _.isNull(null);
+   * // => true
+   *
+   * _.isNull(undefined);
+   * // => false
+   */
+  function isNull(value) {
+    return value === null;
+  }
+
+  /**
+   * Checks if `value` is a number.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a number, else `false`.
+   * @example
+   *
+   * _.isNumber(8.4 * 5);
+   * // => true
+   */
+  function isNumber(value) {
+    return typeof value == 'number' || toString.call(value) == numberClass;
+  }
+
+  /**
+   * Checks if `value` is a regular expression.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a regular expression, else `false`.
+   * @example
+   *
+   * _.isRegExp(/moe/);
+   * // => true
+   */
+  function isRegExp(value) {
+    return value instanceof RegExp || toString.call(value) == regexpClass;
+  }
+
+  /**
+   * Checks if `value` is a string.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is a string, else `false`.
+   * @example
+   *
+   * _.isString('moe');
+   * // => true
+   */
+  function isString(value) {
+    return typeof value == 'string' || toString.call(value) == stringClass;
+  }
+
+  /**
+   * Checks if `value` is `undefined`.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Mixed} value The value to check.
+   * @returns {Boolean} Returns `true`, if the `value` is `undefined`, else `false`.
+   * @example
+   *
+   * _.isUndefined(void 0);
+   * // => true
+   */
+  function isUndefined(value) {
+    return typeof value == 'undefined';
+  }
+
+  /**
+   * Creates a shallow clone of `object` excluding the specified properties.
+   * Property names may be specified as individual arguments or as arrays of
+   * property names. If a `callback` function is passed, it will be executed
+   * for each property in the `object`, omitting the properties `callback`
+   * returns truthy for. The `callback` is bound to `thisArg` and invoked
+   * with three arguments; (value, key, object).
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Object} object The source object.
+   * @param {Function|String} callback|[prop1, prop2, ...] The properties to omit
+   *  or the function called per iteration.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Object} Returns an object without the omitted properties.
+   * @example
+   *
+   * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
+   * // => { 'name': 'moe' }
+   *
+   * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
+   *   return typeof value == 'number';
+   * });
+   * // => { 'name': 'moe' }
+   */
+  function omit(object) {
+    var props = concat.apply(arrayRef, arguments),
+        result = {};
+
+    forIn(object, function(value, key) {
+      if (indexOf(props, key, 1) < 0) {
+        result[key] = value;
+      }
+    });
+    return result;
+  }
+
+  /**
+   * Creates a two dimensional array of the given object's key-value pairs,
+   * i.e. `[[key1, value1], [key2, value2]]`.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Object} object The object to inspect.
+   * @returns {Array} Returns new array of key-value pairs.
+   * @example
+   *
+   * _.pairs({ 'moe': 30, 'larry': 40 });
+   * // => [['moe', 30], ['larry', 40]] (order is not guaranteed)
+   */
+  function pairs(object) {
+    var index = -1,
+        props = keys(object),
+        length = props.length,
+        result = Array(length);
+
+    while (++index < length) {
+      var key = props[index];
+      result[index] = [key, object[key]];
     }
-    return slice.call(array, 0, -((n == undefined || guard) ? 1 : n));
+    return result;
   }
 
   /**
-   * Computes the intersection of all the passed-in arrays.
+   * Creates a shallow clone of `object` composed of the specified properties.
+   * Property names may be specified as individual arguments or as arrays of property
+   * names. If `callback` is passed, it will be executed for each property in the
+   * `object`, picking the properties `callback` returns truthy for. The `callback`
+   * is bound to `thisArg` and invoked with three arguments; (value, key, object).
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} [array1, array2, ...] Arrays to process.
-   * @returns {Array} Returns a new array of unique values, in order, that are
-   *  present in **all** of the arrays.
+   * @category Objects
+   * @param {Object} object The source object.
+   * @param {Array|Function|String} callback|[prop1, prop2, ...] The function called
+   *  per iteration or properties to pick, either as individual arguments or arrays.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Object} Returns an object composed of the picked properties.
    * @example
    *
-   * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
-   * // => [1, 2]
+   * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
+   * // => { 'name': 'moe' }
+   *
+   * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
+   *   return key.charAt(0) != '_';
+   * });
+   * // => { 'name': 'moe' }
    */
-  function intersection(array) {
-    var result = [];
-    if (!array) {
-      return result;
+  function pick(object) {
+    var index = 0,
+        props = concat.apply(arrayRef, arguments),
+        length = props.length,
+        result = {};
+
+    while (++index < length) {
+      var prop = props[index];
+      if (prop in object) {
+        result[prop] = object[prop];
+      }
     }
-    var value,
-        index = -1,
-        length = array.length,
-        others = slice.call(arguments, 1);
+    return result;
+  }
+
+  /**
+   * Creates an array composed of the own enumerable property values of `object`.
+   *
+   * @static
+   * @memberOf _
+   * @category Objects
+   * @param {Object} object The object to inspect.
+   * @returns {Array} Returns a new array of property values.
+   * @example
+   *
+   * _.values({ 'one': 1, 'two': 2, 'three': 3 });
+   * // => [1, 2, 3] (order is not guaranteed)
+   */
+  function values(object) {
+    var index = -1,
+        props = keys(object),
+        length = props.length,
+        result = Array(length);
 
     while (++index < length) {
-      value = array[index];
-      if (indexOf(result, value) < 0 &&
-          every(others, function(other) { return indexOf(other, value) > -1; })) {
-        result.push(value);
-      }
+      result[index] = object[props[index]];
     }
     return result;
   }
 
+  /*--------------------------------------------------------------------------*/
+
   /**
-   * Invokes the method named by `methodName` on each element of `array`.
-   * Additional arguments will be passed to each invoked method. If `methodName`
-   * is a function it will be invoked for, and `this` bound to, each element
-   * of `array`.
+   * Checks if a given `target` element is present in a `collection` using strict
+   * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
+   * as the offset from the end of the collection.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to iterate over.
-   * @param {Function|String} methodName The name of the method to invoke or
-   *  the function invoked per iteration.
-   * @param {Mixed} [arg1, arg2, ...] Arguments to invoke the method with.
-   * @returns {Array} Returns a new array of values returned from each invoked method.
+   * @alias include
+   * @category Collections
+   * @param {Array|Object|String} collection The collection to iterate over.
+   * @param {Mixed} target The value to check for.
+   * @param {Number} [fromIndex=0] The index to search from.
+   * @returns {Boolean} Returns `true` if the `target` element is found, else `false`.
    * @example
    *
-   * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
-   * // => [[1, 5, 7], [1, 2, 3]]
+   * _.contains([1, 2, 3], 1);
+   * // => true
    *
-   * _.invoke([123, 456], String.prototype.split, '');
-   * // => [['1', '2', '3'], ['4', '5', '6']]
+   * _.contains([1, 2, 3], 1, 2);
+   * // => false
+   *
+   * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
+   * // => true
+   *
+   * _.contains('curly', 'ur');
+   * // => true
    */
-  function invoke(array, methodName) {
-    var result = [];
-    if (!array) {
-      return result;
-    }
-    var args = slice.call(arguments, 2),
-        index = -1,
-        length = array.length,
-        isFunc = typeof methodName == 'function';
-
-    while (++index < length) {
-      result[index] = (isFunc ? methodName : array[index][methodName]).apply(array[index], args);
+  function contains(collection, target) {
+    var length = collection ? collection.length : 0,
+        result = false;
+    if (typeof length == 'number') {
+      result = indexOf(collection, target) > -1;
+    } else {
+      forOwn(collection, function(value) {
+        return (result = value === target) && indicatorObject;
+      });
     }
     return result;
   }
 
   /**
-   * Gets the last value of the `array`. Pass `n` to return the lasy `n` values
-   * of the `array`.
+   * Creates an object composed of keys returned from running each element of the
+   * `collection` through the given `callback`. The corresponding value of each key
+   * is the number of times the key was returned by the `callback`. The `callback`
+   * is bound to `thisArg` and invoked with three arguments; (value, index|key, collection).
+   *
+   * If a property name is passed for `callback`, the created "_.pluck" style
+   * callback will return the property value of the given element.
+   *
+   * If an object is passed for `callback`, the created "_.where" style callback
+   * will return `true` for elements that have the properties of the given object,
+   * else `false`.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to query.
-   * @param {Number} [n] The number of elements to return.
-   * @param {Object} [guard] Internally used to allow this method to work with
-   *  others like `_.map` without using their callback `index` argument for `n`.
-   * @returns {Mixed} Returns the last value or an array of the last `n` values
-   *  of `array`.
+   * @category Collections
+   * @param {Array|Object|String} collection The collection to iterate over.
+   * @param {Function|Object|String} [callback=identity] The function called per
+   *  iteration. If a property name or object is passed, it will be used to create
+   *  a "_.pluck" or "_.where" style callback, respectively.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Object} Returns the composed aggregate object.
    * @example
    *
-   * _.last([3, 2, 1]);
-   * // => 1
+   * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
+   * // => { '4': 1, '6': 2 }
+   *
+   * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
+   * // => { '4': 1, '6': 2 }
+   *
+   * _.countBy(['one', 'two', 'three'], 'length');
+   * // => { '3': 2, '5': 1 }
    */
-  function last(array, n, guard) {
-    if (array) {
-      var length = array.length;
-      return (n == undefined || guard) ? array[length - 1] : slice.call(array, -n || length);
-    }
+  function countBy(collection, callback, thisArg) {
+    var result = {};
+    callback = createCallback(callback, thisArg);
+
+    forEach(collection, function(value, key, collection) {
+      key = String(callback(value, key, collection));
+      (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
+    });
+    return result;
   }
 
   /**
-   * Gets the index at which the last occurrence of `value` is found using
-   * strict equality for comparisons, i.e. `===`.
+   * Checks if the `callback` returns a truthy value for **all** elements of a
+   * `collection`. The `callback` is bound to `thisArg` and invoked with three
+   * arguments; (value, index|key, collection).
+   *
+   * If a property name is passed for `callback`, the created "_.pluck" style
+   * callback will return the property value of the given element.
+   *
+   * If an object is passed for `callback`, the created "_.where" style callback
+   * will return `true` for elements that have the properties of the given object,
+   * else `false`.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to search.
-   * @param {Mixed} value The value to search for.
-   * @param {Number} [fromIndex=array.length-1] The index to start searching from.
-   * @returns {Number} Returns the index of the matched value or `-1`.
+   * @alias all
+   * @category Collections
+   * @param {Array|Object|String} collection The collection to iterate over.
+   * @param {Function|Object|String} [callback=identity] The function called per
+   *  iteration. If a property name or object is passed, it will be used to create
+   *  a "_.pluck" or "_.where" style callback, respectively.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Boolean} Returns `true` if all elements pass the callback check,
+   *  else `false`.
    * @example
    *
-   * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
-   * // => 4
+   * _.every([true, 1, null, 'yes'], Boolean);
+   * // => false
    *
-   * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
-   * // => 1
+   * var stooges = [
+   *   { 'name': 'moe', 'age': 40 },
+   *   { 'name': 'larry', 'age': 50 }
+   * ];
+   *
+   * // using "_.pluck" callback shorthand
+   * _.every(stooges, 'age');
+   * // => true
+   *
+   * // using "_.where" callback shorthand
+   * _.every(stooges, { 'age': 50 });
+   * // => false
    */
-  function lastIndexOf(array, value, fromIndex) {
-    if (!array) {
-      return -1;
-    }
-    var index = array.length;
-    if (fromIndex && typeof fromIndex == 'number') {
-      index = (fromIndex < 0 ? Math.max(0, index + fromIndex) : Math.min(fromIndex, index - 1)) + 1;
-    }
-    while (index--) {
-      if (array[index] === value) {
-        return index;
+  function every(collection, callback, thisArg) {
+    var result = true;
+    callback = createCallback(callback, thisArg);
+
+    var index = -1,
+        length = collection ? collection.length : 0;
+
+    if (typeof length == 'number') {
+      while (++index < length) {
+        if (!(result = !!callback(collection[index], index, collection))) {
+          break;
+        }
       }
+    } else {
+      forOwn(collection, function(value, index, collection) {
+        return !(result = !!callback(value, index, collection)) && indicatorObject;
+      });
     }
-    return -1;
+    return result;
   }
 
   /**
-   * Retrieves the maximum value of an `array`. If `callback` is passed,
-   * it will be executed for each value in the `array` to generate the
-   * criterion by which the value is ranked. The `callback` is bound to
-   * `thisArg` and invoked with 3 arguments; (value, index, array).
+   * Examines each element in a `collection`, returning an array of all elements
+   * the `callback` returns truthy for. The `callback` is bound to `thisArg` and
+   * invoked with three arguments; (value, index|key, collection).
+   *
+   * If a property name is passed for `callback`, the created "_.pluck" style
+   * callback will return the property value of the given element.
+   *
+   * If an object is passed for `callback`, the created "_.where" style callback
+   * will return `true` for elements that have the properties of the given object,
+   * else `false`.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to iterate over.
-   * @param {Function} [callback] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Mixed} Returns the maximum value.
+   * @alias select
+   * @category Collections
+   * @param {Array|Object|String} collection The collection to iterate over.
+   * @param {Function|Object|String} [callback=identity] The function called per
+   *  iteration. If a property name or object is passed, it will be used to create
+   *  a "_.pluck" or "_.where" style callback, respectively.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Array} Returns a new array of elements that passed the callback check.
    * @example
    *
-   * var stooges = [
-   *   { 'name': 'moe', 'age': 40 },
-   *   { 'name': 'larry', 'age': 50 },
-   *   { 'name': 'curly', 'age': 60 }
+   * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
+   * // => [2, 4, 6]
+   *
+   * var food = [
+   *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
+   *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
    * ];
    *
-   * _.max(stooges, function(stooge) { return stooge.age; });
-   * // => { 'name': 'curly', 'age': 60 };
+   * // using "_.pluck" callback shorthand
+   * _.filter(food, 'organic');
+   * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
+   *
+   * // using "_.where" callback shorthand
+   * _.filter(food, { 'type': 'fruit' });
+   * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
    */
-  function max(array, callback, thisArg) {
-    var computed = -Infinity,
-        result = computed;
+  function filter(collection, callback, thisArg) {
+    var result = [];
+    callback = createCallback(callback, thisArg);
 
-    if (!array) {
-      return result;
-    }
-    var current,
-        index = -1,
-        length = array.length;
+    var index = -1,
+        length = collection ? collection.length : 0;
 
-    if (!callback) {
+    if (typeof length == 'number') {
       while (++index < length) {
-        if (array[index] > result) {
-          result = array[index];
+        var value = collection[index];
+        if (callback(value, index, collection)) {
+          result.push(value);
         }
       }
-      return result;
-    }
-    if (thisArg) {
-      callback = iteratorBind(callback, thisArg);
-    }
-    while (++index < length) {
-      current = callback(array[index], index, array);
-      if (current > computed) {
-        computed = current;
-        result = array[index];
-      }
+    } else {
+      forOwn(collection, function(value, index, collection) {
+        if (callback(value, index, collection)) {
+          result.push(value);
+        }
+      });
     }
     return result;
   }
 
   /**
-   * Retrieves the minimum value of an `array`. If `callback` is passed,
-   * it will be executed for each value in the `array` to generate the
-   * criterion by which the value is ranked. The `callback` is bound to `thisArg`
-   * and invoked with 3 arguments; (value, index, array).
+   * Examines each element in a `collection`, returning the first that the `callback`
+   * returns truthy for. The `callback` is bound to `thisArg` and invoked with three
+   * arguments; (value, index|key, collection).
+   *
+   * If a property name is passed for `callback`, the created "_.pluck" style
+   * callback will return the property value of the given element.
+   *
+   * If an object is passed for `callback`, the created "_.where" style callback
+   * will return `true` for elements that have the properties of the given object,
+   * else `false`.
    *
    * @static
    * @memberOf _
-   * @category Arrays
-   * @param {Array} array The array to iterate over.
-   * @param {Function} [callback] The function called per iteration.
-   * @param {Mixed} [thisArg] The `this` binding for the callback.
-   * @returns {Mixed} Returns the minimum value.
+   * @alias detect
+   * @category Collections
+   * @param {Array|Object|String} collection The collection to iterate over.
+   * @param {Function|Object|String} [callback=identity] The function called per
+   *  iteration. If a property name or object is passed, it will be used to create
+   *  a "_.pluck" or "_.where" style callback, respectively.
+   * @param {Mixed} [thisArg] The `this` binding of `callback`.
+   * @returns {Mixed} Returns the found element, else `undefined`.
    * @example
    *
-   * _.min([10, 5, 100, 2, 1000]);
+   * _.find([1, 2, 3, 4], function(num) { return num % 2 == 0; });
    * // => 2
+   *
+   * var food = [
+   *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
+   *   { 'name': 'banana', 'organic': true,  'type': 'fruit' },
+   *   { 'name': 'beet',   'organic': false, 'type': 'vegetable' }
+   * ];
+   *
+   * // using "_.where" callback shorthand
+   * _.find(food, { 'type': 'vegetable' });
+   * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
+   *
+   * // using "_.pluck" callback shorthand
+   * _.find(food, 'organic');
+   * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
    */
-  function min(array, callback, thisArg) {
-    var computed = Infinity,
-        result = computed;
+  function find(col

<TRUNCATED>

Mime
View raw message