index.js
  1  /**
  2   * lodash (Custom Build) <https://lodash.com/>
  3   * Build: `lodash modularize exports="npm" -o ./`
  4   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
  5   * Released under MIT license <https://lodash.com/license>
  6   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
  7   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  8   */
  9  
 10  /** Used as references for various `Number` constants. */
 11  var MAX_SAFE_INTEGER = 9007199254740991;
 12  
 13  /** `Object#toString` result references. */
 14  var argsTag = '[object Arguments]',
 15      funcTag = '[object Function]',
 16      genTag = '[object GeneratorFunction]';
 17  
 18  /** Used to detect unsigned integer values. */
 19  var reIsUint = /^(?:0|[1-9]\d*)$/;
 20  
 21  /**
 22   * A faster alternative to `Function#apply`, this function invokes `func`
 23   * with the `this` binding of `thisArg` and the arguments of `args`.
 24   *
 25   * @private
 26   * @param {Function} func The function to invoke.
 27   * @param {*} thisArg The `this` binding of `func`.
 28   * @param {Array} args The arguments to invoke `func` with.
 29   * @returns {*} Returns the result of `func`.
 30   */
 31  function apply(func, thisArg, args) {
 32    switch (args.length) {
 33      case 0: return func.call(thisArg);
 34      case 1: return func.call(thisArg, args[0]);
 35      case 2: return func.call(thisArg, args[0], args[1]);
 36      case 3: return func.call(thisArg, args[0], args[1], args[2]);
 37    }
 38    return func.apply(thisArg, args);
 39  }
 40  
 41  /**
 42   * The base implementation of `_.times` without support for iteratee shorthands
 43   * or max array length checks.
 44   *
 45   * @private
 46   * @param {number} n The number of times to invoke `iteratee`.
 47   * @param {Function} iteratee The function invoked per iteration.
 48   * @returns {Array} Returns the array of results.
 49   */
 50  function baseTimes(n, iteratee) {
 51    var index = -1,
 52        result = Array(n);
 53  
 54    while (++index < n) {
 55      result[index] = iteratee(index);
 56    }
 57    return result;
 58  }
 59  
 60  /** Used for built-in method references. */
 61  var objectProto = Object.prototype;
 62  
 63  /** Used to check objects for own properties. */
 64  var hasOwnProperty = objectProto.hasOwnProperty;
 65  
 66  /**
 67   * Used to resolve the
 68   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 69   * of values.
 70   */
 71  var objectToString = objectProto.toString;
 72  
 73  /** Built-in value references. */
 74  var propertyIsEnumerable = objectProto.propertyIsEnumerable;
 75  
 76  /* Built-in method references for those with the same name as other `lodash` methods. */
 77  var nativeMax = Math.max;
 78  
 79  /**
 80   * Creates an array of the enumerable property names of the array-like `value`.
 81   *
 82   * @private
 83   * @param {*} value The value to query.
 84   * @param {boolean} inherited Specify returning inherited property names.
 85   * @returns {Array} Returns the array of property names.
 86   */
 87  function arrayLikeKeys(value, inherited) {
 88    // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
 89    // Safari 9 makes `arguments.length` enumerable in strict mode.
 90    var result = (isArray(value) || isArguments(value))
 91      ? baseTimes(value.length, String)
 92      : [];
 93  
 94    var length = result.length,
 95        skipIndexes = !!length;
 96  
 97    for (var key in value) {
 98      if ((inherited || hasOwnProperty.call(value, key)) &&
 99          !(skipIndexes && (key == 'length' || isIndex(key, length)))) {
100        result.push(key);
101      }
102    }
103    return result;
104  }
105  
106  /**
107   * Used by `_.defaults` to customize its `_.assignIn` use.
108   *
109   * @private
110   * @param {*} objValue The destination value.
111   * @param {*} srcValue The source value.
112   * @param {string} key The key of the property to assign.
113   * @param {Object} object The parent object of `objValue`.
114   * @returns {*} Returns the value to assign.
115   */
116  function assignInDefaults(objValue, srcValue, key, object) {
117    if (objValue === undefined ||
118        (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) {
119      return srcValue;
120    }
121    return objValue;
122  }
123  
124  /**
125   * Assigns `value` to `key` of `object` if the existing value is not equivalent
126   * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
127   * for equality comparisons.
128   *
129   * @private
130   * @param {Object} object The object to modify.
131   * @param {string} key The key of the property to assign.
132   * @param {*} value The value to assign.
133   */
134  function assignValue(object, key, value) {
135    var objValue = object[key];
136    if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
137        (value === undefined && !(key in object))) {
138      object[key] = value;
139    }
140  }
141  
142  /**
143   * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
144   *
145   * @private
146   * @param {Object} object The object to query.
147   * @returns {Array} Returns the array of property names.
148   */
149  function baseKeysIn(object) {
150    if (!isObject(object)) {
151      return nativeKeysIn(object);
152    }
153    var isProto = isPrototype(object),
154        result = [];
155  
156    for (var key in object) {
157      if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
158        result.push(key);
159      }
160    }
161    return result;
162  }
163  
164  /**
165   * The base implementation of `_.rest` which doesn't validate or coerce arguments.
166   *
167   * @private
168   * @param {Function} func The function to apply a rest parameter to.
169   * @param {number} [start=func.length-1] The start position of the rest parameter.
170   * @returns {Function} Returns the new function.
171   */
172  function baseRest(func, start) {
173    start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
174    return function() {
175      var args = arguments,
176          index = -1,
177          length = nativeMax(args.length - start, 0),
178          array = Array(length);
179  
180      while (++index < length) {
181        array[index] = args[start + index];
182      }
183      index = -1;
184      var otherArgs = Array(start + 1);
185      while (++index < start) {
186        otherArgs[index] = args[index];
187      }
188      otherArgs[start] = array;
189      return apply(func, this, otherArgs);
190    };
191  }
192  
193  /**
194   * Copies properties of `source` to `object`.
195   *
196   * @private
197   * @param {Object} source The object to copy properties from.
198   * @param {Array} props The property identifiers to copy.
199   * @param {Object} [object={}] The object to copy properties to.
200   * @param {Function} [customizer] The function to customize copied values.
201   * @returns {Object} Returns `object`.
202   */
203  function copyObject(source, props, object, customizer) {
204    object || (object = {});
205  
206    var index = -1,
207        length = props.length;
208  
209    while (++index < length) {
210      var key = props[index];
211  
212      var newValue = customizer
213        ? customizer(object[key], source[key], key, object, source)
214        : undefined;
215  
216      assignValue(object, key, newValue === undefined ? source[key] : newValue);
217    }
218    return object;
219  }
220  
221  /**
222   * Creates a function like `_.assign`.
223   *
224   * @private
225   * @param {Function} assigner The function to assign values.
226   * @returns {Function} Returns the new assigner function.
227   */
228  function createAssigner(assigner) {
229    return baseRest(function(object, sources) {
230      var index = -1,
231          length = sources.length,
232          customizer = length > 1 ? sources[length - 1] : undefined,
233          guard = length > 2 ? sources[2] : undefined;
234  
235      customizer = (assigner.length > 3 && typeof customizer == 'function')
236        ? (length--, customizer)
237        : undefined;
238  
239      if (guard && isIterateeCall(sources[0], sources[1], guard)) {
240        customizer = length < 3 ? undefined : customizer;
241        length = 1;
242      }
243      object = Object(object);
244      while (++index < length) {
245        var source = sources[index];
246        if (source) {
247          assigner(object, source, index, customizer);
248        }
249      }
250      return object;
251    });
252  }
253  
254  /**
255   * Checks if `value` is a valid array-like index.
256   *
257   * @private
258   * @param {*} value The value to check.
259   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
260   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
261   */
262  function isIndex(value, length) {
263    length = length == null ? MAX_SAFE_INTEGER : length;
264    return !!length &&
265      (typeof value == 'number' || reIsUint.test(value)) &&
266      (value > -1 && value % 1 == 0 && value < length);
267  }
268  
269  /**
270   * Checks if the given arguments are from an iteratee call.
271   *
272   * @private
273   * @param {*} value The potential iteratee value argument.
274   * @param {*} index The potential iteratee index or key argument.
275   * @param {*} object The potential iteratee object argument.
276   * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
277   *  else `false`.
278   */
279  function isIterateeCall(value, index, object) {
280    if (!isObject(object)) {
281      return false;
282    }
283    var type = typeof index;
284    if (type == 'number'
285          ? (isArrayLike(object) && isIndex(index, object.length))
286          : (type == 'string' && index in object)
287        ) {
288      return eq(object[index], value);
289    }
290    return false;
291  }
292  
293  /**
294   * Checks if `value` is likely a prototype object.
295   *
296   * @private
297   * @param {*} value The value to check.
298   * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
299   */
300  function isPrototype(value) {
301    var Ctor = value && value.constructor,
302        proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
303  
304    return value === proto;
305  }
306  
307  /**
308   * This function is like
309   * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
310   * except that it includes inherited enumerable properties.
311   *
312   * @private
313   * @param {Object} object The object to query.
314   * @returns {Array} Returns the array of property names.
315   */
316  function nativeKeysIn(object) {
317    var result = [];
318    if (object != null) {
319      for (var key in Object(object)) {
320        result.push(key);
321      }
322    }
323    return result;
324  }
325  
326  /**
327   * Performs a
328   * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
329   * comparison between two values to determine if they are equivalent.
330   *
331   * @static
332   * @memberOf _
333   * @since 4.0.0
334   * @category Lang
335   * @param {*} value The value to compare.
336   * @param {*} other The other value to compare.
337   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
338   * @example
339   *
340   * var object = { 'a': 1 };
341   * var other = { 'a': 1 };
342   *
343   * _.eq(object, object);
344   * // => true
345   *
346   * _.eq(object, other);
347   * // => false
348   *
349   * _.eq('a', 'a');
350   * // => true
351   *
352   * _.eq('a', Object('a'));
353   * // => false
354   *
355   * _.eq(NaN, NaN);
356   * // => true
357   */
358  function eq(value, other) {
359    return value === other || (value !== value && other !== other);
360  }
361  
362  /**
363   * Checks if `value` is likely an `arguments` object.
364   *
365   * @static
366   * @memberOf _
367   * @since 0.1.0
368   * @category Lang
369   * @param {*} value The value to check.
370   * @returns {boolean} Returns `true` if `value` is an `arguments` object,
371   *  else `false`.
372   * @example
373   *
374   * _.isArguments(function() { return arguments; }());
375   * // => true
376   *
377   * _.isArguments([1, 2, 3]);
378   * // => false
379   */
380  function isArguments(value) {
381    // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
382    return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
383      (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
384  }
385  
386  /**
387   * Checks if `value` is classified as an `Array` object.
388   *
389   * @static
390   * @memberOf _
391   * @since 0.1.0
392   * @category Lang
393   * @param {*} value The value to check.
394   * @returns {boolean} Returns `true` if `value` is an array, else `false`.
395   * @example
396   *
397   * _.isArray([1, 2, 3]);
398   * // => true
399   *
400   * _.isArray(document.body.children);
401   * // => false
402   *
403   * _.isArray('abc');
404   * // => false
405   *
406   * _.isArray(_.noop);
407   * // => false
408   */
409  var isArray = Array.isArray;
410  
411  /**
412   * Checks if `value` is array-like. A value is considered array-like if it's
413   * not a function and has a `value.length` that's an integer greater than or
414   * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
415   *
416   * @static
417   * @memberOf _
418   * @since 4.0.0
419   * @category Lang
420   * @param {*} value The value to check.
421   * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
422   * @example
423   *
424   * _.isArrayLike([1, 2, 3]);
425   * // => true
426   *
427   * _.isArrayLike(document.body.children);
428   * // => true
429   *
430   * _.isArrayLike('abc');
431   * // => true
432   *
433   * _.isArrayLike(_.noop);
434   * // => false
435   */
436  function isArrayLike(value) {
437    return value != null && isLength(value.length) && !isFunction(value);
438  }
439  
440  /**
441   * This method is like `_.isArrayLike` except that it also checks if `value`
442   * is an object.
443   *
444   * @static
445   * @memberOf _
446   * @since 4.0.0
447   * @category Lang
448   * @param {*} value The value to check.
449   * @returns {boolean} Returns `true` if `value` is an array-like object,
450   *  else `false`.
451   * @example
452   *
453   * _.isArrayLikeObject([1, 2, 3]);
454   * // => true
455   *
456   * _.isArrayLikeObject(document.body.children);
457   * // => true
458   *
459   * _.isArrayLikeObject('abc');
460   * // => false
461   *
462   * _.isArrayLikeObject(_.noop);
463   * // => false
464   */
465  function isArrayLikeObject(value) {
466    return isObjectLike(value) && isArrayLike(value);
467  }
468  
469  /**
470   * Checks if `value` is classified as a `Function` object.
471   *
472   * @static
473   * @memberOf _
474   * @since 0.1.0
475   * @category Lang
476   * @param {*} value The value to check.
477   * @returns {boolean} Returns `true` if `value` is a function, else `false`.
478   * @example
479   *
480   * _.isFunction(_);
481   * // => true
482   *
483   * _.isFunction(/abc/);
484   * // => false
485   */
486  function isFunction(value) {
487    // The use of `Object#toString` avoids issues with the `typeof` operator
488    // in Safari 8-9 which returns 'object' for typed array and other constructors.
489    var tag = isObject(value) ? objectToString.call(value) : '';
490    return tag == funcTag || tag == genTag;
491  }
492  
493  /**
494   * Checks if `value` is a valid array-like length.
495   *
496   * **Note:** This method is loosely based on
497   * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
498   *
499   * @static
500   * @memberOf _
501   * @since 4.0.0
502   * @category Lang
503   * @param {*} value The value to check.
504   * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
505   * @example
506   *
507   * _.isLength(3);
508   * // => true
509   *
510   * _.isLength(Number.MIN_VALUE);
511   * // => false
512   *
513   * _.isLength(Infinity);
514   * // => false
515   *
516   * _.isLength('3');
517   * // => false
518   */
519  function isLength(value) {
520    return typeof value == 'number' &&
521      value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
522  }
523  
524  /**
525   * Checks if `value` is the
526   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
527   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
528   *
529   * @static
530   * @memberOf _
531   * @since 0.1.0
532   * @category Lang
533   * @param {*} value The value to check.
534   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
535   * @example
536   *
537   * _.isObject({});
538   * // => true
539   *
540   * _.isObject([1, 2, 3]);
541   * // => true
542   *
543   * _.isObject(_.noop);
544   * // => true
545   *
546   * _.isObject(null);
547   * // => false
548   */
549  function isObject(value) {
550    var type = typeof value;
551    return !!value && (type == 'object' || type == 'function');
552  }
553  
554  /**
555   * Checks if `value` is object-like. A value is object-like if it's not `null`
556   * and has a `typeof` result of "object".
557   *
558   * @static
559   * @memberOf _
560   * @since 4.0.0
561   * @category Lang
562   * @param {*} value The value to check.
563   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
564   * @example
565   *
566   * _.isObjectLike({});
567   * // => true
568   *
569   * _.isObjectLike([1, 2, 3]);
570   * // => true
571   *
572   * _.isObjectLike(_.noop);
573   * // => false
574   *
575   * _.isObjectLike(null);
576   * // => false
577   */
578  function isObjectLike(value) {
579    return !!value && typeof value == 'object';
580  }
581  
582  /**
583   * This method is like `_.assignIn` except that it accepts `customizer`
584   * which is invoked to produce the assigned values. If `customizer` returns
585   * `undefined`, assignment is handled by the method instead. The `customizer`
586   * is invoked with five arguments: (objValue, srcValue, key, object, source).
587   *
588   * **Note:** This method mutates `object`.
589   *
590   * @static
591   * @memberOf _
592   * @since 4.0.0
593   * @alias extendWith
594   * @category Object
595   * @param {Object} object The destination object.
596   * @param {...Object} sources The source objects.
597   * @param {Function} [customizer] The function to customize assigned values.
598   * @returns {Object} Returns `object`.
599   * @see _.assignWith
600   * @example
601   *
602   * function customizer(objValue, srcValue) {
603   *   return _.isUndefined(objValue) ? srcValue : objValue;
604   * }
605   *
606   * var defaults = _.partialRight(_.assignInWith, customizer);
607   *
608   * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
609   * // => { 'a': 1, 'b': 2 }
610   */
611  var assignInWith = createAssigner(function(object, source, srcIndex, customizer) {
612    copyObject(source, keysIn(source), object, customizer);
613  });
614  
615  /**
616   * Assigns own and inherited enumerable string keyed properties of source
617   * objects to the destination object for all destination properties that
618   * resolve to `undefined`. Source objects are applied from left to right.
619   * Once a property is set, additional values of the same property are ignored.
620   *
621   * **Note:** This method mutates `object`.
622   *
623   * @static
624   * @since 0.1.0
625   * @memberOf _
626   * @category Object
627   * @param {Object} object The destination object.
628   * @param {...Object} [sources] The source objects.
629   * @returns {Object} Returns `object`.
630   * @see _.defaultsDeep
631   * @example
632   *
633   * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 });
634   * // => { 'a': 1, 'b': 2 }
635   */
636  var defaults = baseRest(function(args) {
637    args.push(undefined, assignInDefaults);
638    return apply(assignInWith, undefined, args);
639  });
640  
641  /**
642   * Creates an array of the own and inherited enumerable property names of `object`.
643   *
644   * **Note:** Non-object values are coerced to objects.
645   *
646   * @static
647   * @memberOf _
648   * @since 3.0.0
649   * @category Object
650   * @param {Object} object The object to query.
651   * @returns {Array} Returns the array of property names.
652   * @example
653   *
654   * function Foo() {
655   *   this.a = 1;
656   *   this.b = 2;
657   * }
658   *
659   * Foo.prototype.c = 3;
660   *
661   * _.keysIn(new Foo);
662   * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
663   */
664  function keysIn(object) {
665    return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
666  }
667  
668  module.exports = defaults;