From 62936c28f7abcec2380aa668e5d896edcbd76c74 Mon Sep 17 00:00:00 2001 From: Andrea Scartabelli Date: Tue, 18 Jun 2019 10:22:04 +0200 Subject: [PATCH] Version bump to 0.58.0 --- README.md | 23 +++++++++++++++-------- dist/lamb.esm.js | 12 ++++++------ dist/lamb.esm.min.js | 2 +- dist/lamb.esm.min.js.map | 2 +- dist/lamb.js | 12 ++++++------ dist/lamb.min.js | 2 +- dist/lamb.min.js.map | 2 +- package-lock.json | 2 +- package.json | 8 ++------ src/array/findLastWhere.js | 4 ++-- src/array/findWhere.js | 4 ++-- src/logic/adapter.js | 2 +- 12 files changed, 39 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 7632368..0536209 100644 --- a/README.md +++ b/README.md @@ -51,18 +51,20 @@ or Doing so a `lamb` variable will be created in the global object. The source map for the minified file is in the same `dist` folder. +Since version 0.58.0 there is also a one file ES modules build, always in the `dist` folder, named `lamb.esm.js` and its minified version `lamb.esm.min.js`. + Lamb it's also delivered on a CDN, courtesy of [cdnjs](https://cdnjs.com/), [jsDelivr](https://www.jsdelivr.com/) and [unpkg](https://unpkg.com/): ```html - + ``` ```html - + ``` ```html - + ``` Please note that Lamb is served by jsDelivr since version 0.42.0. @@ -113,6 +115,16 @@ You can check the [recent](#recent_changes) or the [full](https://ascartabelli.g ## Recent changes You can also check the [full changelog](https://ascartabelli.github.io/lamb/changelog.html). +- **v0.58.0 - *2019/06/18** + - Added one file ES modules build + - **API change**: `invoker` now accepts an array of bound arguments + - **API change**: benched `immutable` for the moment being + - Added `join` and `joinWith` + - Added `findLast`, `findLastWhere`, `findLastIndex`, `findLastIndexWhere` + - Added `dropLastWhile` and `takeLastWhile` + - Switched from uglify-js to terser + - Updated docs, linting and tests + - **v0.57.0 - *2019/02/12*** - Splitted the library into ES modules - **API change**: `sort`, `sortWith` and `sortedInsert` now accept an array of sorters @@ -134,8 +146,3 @@ You can also check the [full changelog](https://ascartabelli.github.io/lamb/chan - **Fixed**: `setPath` and `updatePath` weren't returning unary functions, and further arguments would have overwritten the previous ones - Updated doc comments - Updated linting rules - -- **v0.54.0 - *2017/08/01*** - - Added `mapValues` and `mapValuesWith` - - Added "@since" tags to doc comments - - Added linting for tests diff --git a/dist/lamb.esm.js b/dist/lamb.esm.js index a2e32c3..2146a8c 100644 --- a/dist/lamb.esm.js +++ b/dist/lamb.esm.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli -* @version 0.58.0-alpha.9 +* @version 0.58.0 * @module lamb * @license MIT */ @@ -1547,8 +1547,8 @@ function findLast (arrayLike, predicate) { var findLastIndexWhere = _curry2(findLastIndex, true); /** - * A curried version of {@link module:lamb.findLast|findLast} expecting the array-like object - * to search. + * A curried version of {@link module:lamb.findLast|findLast} that uses the given + * predicate to build a function expecting the array-like object to search. * @example * var isEven = function (n) { return n % 2 === 0; }; * var findEven = _.findLastWhere(isEven); @@ -1571,8 +1571,8 @@ var findLastIndexWhere = _curry2(findLastIndex, true); var findLastWhere = _curry2(findLast, true); /** - * A curried version of {@link module:lamb.find|find} expecting the array-like object - * to search. + * A curried version of {@link module:lamb.find|find} that uses the given + * predicate to build a function expecting the array-like object to search. * @example * var isEven = function (n) { return n % 2 === 0; }; * var findEven = _.findWhere(isEven); @@ -4115,7 +4115,7 @@ function unary (fn) { * to mimic conditional logic or pattern matching, and also to build polymorphic functions. * @example * var isEven = function (n) { return n % 2 === 0; }; - * var filterString = _.compose(_.invoker("join", [""]), _.filter); + * var filterString = _.compose(_.joinWith(""), _.filter); * var filterAdapter = _.adapter([ * _.invoker("filter"), * _.case(_.isType("String"), filterString) diff --git a/dist/lamb.esm.min.js b/dist/lamb.esm.min.js index 7be0dc8..fcbc861 100644 --- a/dist/lamb.esm.min.js +++ b/dist/lamb.esm.min.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli -* @version 0.58.0-alpha.9 +* @version 0.58.0 * @module lamb * @license MIT */ diff --git a/dist/lamb.esm.min.js.map b/dist/lamb.esm.min.js.map index e16bcf1..c6301e5 100644 --- a/dist/lamb.esm.min.js.map +++ b/dist/lamb.esm.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lamb.esm.js"],"names":["__","always","value","areSVZ","a","b","binary","fn","call","this","clamp","n","min","max","NaN","partial","args","Array","isArray","apply","arguments","boundArg","lastIdx","newArgs","argsLen","length","i","len","_makePartial3","shouldAritize","clampWithin","identity","compose","MAX_ARRAY_LENGTH","MAX_SAFE_INTEGER","_toArrayLength","forEach","arrayLike","iteratee","generic","Function","bind","isNull","isUndefined","isNil","_curry2","isRightCurry","isSVZ","map","result","mapWith","partialRight","boundArgs","j","_makeReducer","step","accumulator","initialValue","nCalls","idx","TypeError","reduce","reduceWith","_toInteger","Math","floor","abs","slice","start","end","begin","upTo","resultLen","sliceAt","objectProtoToString","Object","prototype","toString","type","appendTo","concat","append","isIn","contains","_groupWith","makeValue","element","key","count","countBy","filter","predicate","push","not","uniquesBy","seen","uniques","difference","other","isNotInOther","dropFrom","drop","_getLastHitIndex","fromLast","increment","_takeOrDropWhile","isTake","idxFrom","idxTo","lastHitIndex","dropLastWhile","dropWhile","_makeArrayChecker","defaultResult","everyIn","every","filterWith","_findIndex","findIndex","find","findIndexWhere","findLastIndex","findLast","findLastIndexWhere","findLastWhere","findWhere","flatMap","array","el","arr","v","rLen","flatMapWith","_flatten","isDeep","output","vLen","_makeArrayFlattener","flatten","_toNaturalIndex","getIndex","index","getAt","group","groupBy","head","indexBy","init","insert","splice","insertAt","intersection","lenA","join","separator","String","joinWith","last","_argsToArrayFrom","list","partition","partitionWith","getIn","obj","getKey","pluck","pluckKey","pullFrom","values","pull","reduceRight","reduceRightWith","reverse","ofs","rotate","amount","shift","rotateBy","_setIndex","updater","setAt","aritize","arity","setIndex","shallowFlatten","someIn","some","_compareWith","criteria","criterion","compare","isDescending","_comparer","_sorter","reader","comparer","_makeCriterion","_makeCriteria","sorters","sort","_getInsertionIndex","pivot","sortedInsert","sorter","sorterDesc","sortWith","tail","takeFrom","take","takeLastWhile","takeWhile","transpose","minLen","elementLen","_makeTypeErrorFor","desiredType","toLowerCase","pipe","functions","unionBy","union","updateAt","updateIndex","zip","zipWithIndex","application","applyTo","_asPartial","argsHolder","asPartial","collect","_currier","isAutoCurry","holderLen","newArgsLen","_curry3","c","_curry","curry","curryable","curryableRight","curryRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","flip","getArgAt","_invoker","methodName","target","method","boundArgsLen","finalArgsLen","finalArgs","invoker","invokerOn","mapArgs","mapper","tapArgs","tappers","tappersLen","throttle","lastCall","now","Date","unary","adapter","_checkPredicates","checkAll","predicates","allOf","anyOf","areSame","case_","condition","trueFn","falseFn","gt","gte","is","isGT","isGTE","lt","isLT","lte","isLTE","unless","when","sum","add","subtract","deduct","divide","divideBy","generate","limit","isFinite_","isFinite","isInteger","isSafeInteger","modulo","multiply","multiplyBy","randomInt","random","_forceToNumber","range","ceil","remainder","_isOwnEnumerable","propertyIsEnumerable","_safeEnumerables","_isEnumerable","indexOf","_getPathKey","includeNonEnumerables","_getPathInfo","parts","walkNonEnumerables","isValid","_toPathParts","path","split","getPathIn","checker","message","keyPaths","pathSeparator","getValues","_unsafeKeyListFrom","getKeys","enumerables","fromPairs","pairsList","pair","getPath","has","hasKey","hasOwn","hasOwnProperty","hasOwnKey","hasKeyValue","hasPathValue","pathInfo","_safeKeys","keys","keySatisfies","make","names","valuesLen","mapValues","source","mapValuesWith","_merge","merge","mergeOwn","_keyToPairIn","_pairsFrom","ownPairs","_valuesFrom","ownValues","pairs","pathExistsIn","pathExists","pathSatisfies","pick","whitelist","pickIf","pickKeys","rename","keysMap","oldKeys","prop","renameKeys","renameWith","_setIn","setIn","setKey","_isArrayIndex","_setPathIn","partsLen","targetKey","setPathIn","setPath","skip","blacklist","props","skipIf","skipKeys","_tearFrom","tear","tearOwn","updateIn","updateKey","updatePathIn","updatePath","validate","checkers","errors","_checker","validateWith","_repeat","times","_getPadding","char","padLeft","padRight","repeat","_search","search","testWith","pattern","s","isInstanceOf","constructor","isType","typeName"],"mappings":"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","file":"lamb.esm.min.js","sourcesContent":["/**\n* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n* @author Andrea Scartabelli \n* @version 0.58.0-alpha.9\n* @module lamb\n* @license MIT\n*/\n/**\n * The placeholder object used in partial application.\n * @memberof module:lamb\n * @alias module:lamb.__\n * @category Special properties\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.57.0\n * @type {Object}\n */\nvar __ = {};\n\n/**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\nfunction always (value) {\n return function () {\n return value;\n };\n}\n\n/**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\nfunction areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n}\n\n/**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n}\n\n/**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\nfunction clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n}\n\n/**\n * Builds a partially applied function.
\n * The {@link module:lamb.__|__} object can be used as a placeholder for arguments.
\n * @example\n * var __ = _.__;\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [__, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\nfunction partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = boundArg === __ ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n}\n\n/**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\nfunction _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [__, a, b]);\n };\n}\n\n/**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\nvar clampWithin = _makePartial3(clamp);\n\n/**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\nfunction identity (value) {\n return value;\n}\n\n/**\n * Returns a function that is the composition of the functions given as parameters.\n * The first function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {Function} a\n * @param {Function} b\n * @returns {Function}\n */\nfunction compose (a, b) {\n return arguments.length ? function () {\n return a.call(this, b.apply(this, arguments));\n } : identity;\n}\n\nvar MAX_ARRAY_LENGTH = 4294967295;\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\nfunction _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n}\n\n/* eslint-disable jsdoc/require-returns-check */\n\n/**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\nfunction forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n}\n\n/**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\nvar generic = Function.bind.bind(Function.call);\n\n/**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isNull (value) {\n return value === null;\n}\n\n/**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isUndefined (value) {\n return value === void 0;\n}\n\n/**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isNil (value) {\n return isNull(value) || isUndefined(value);\n}\n\n/**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\nfunction _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n}\n\n/**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\nvar isSVZ = _curry2(areSVZ);\n\n/**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\nfunction map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\nvar mapWith = _curry2(map, true);\n\n/**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var __ = _.__;\n * var f1 = _.partial(_.list, [\"a\", __, __, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", __, __, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\nfunction partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = boundArg === __ ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n}\n\n/**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\nfunction _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n}\n\n/**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\nvar reduce = _makeReducer(1);\n\n/**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\nvar reduceWith = _makePartial3(reduce, true);\n\n/**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\nfunction _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n}\n\n/**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\nfunction slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n}\n\n/**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\nvar sliceAt = _makePartial3(slice);\n\nvar objectProtoToString = Object.prototype.toString;\n\n/**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\nfunction type (value) {\n return objectProtoToString.call(value).slice(8, -1);\n}\n\n/**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\nfunction appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n}\n\n/**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\nvar append = _curry2(appendTo, true);\n\n/**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\nvar contains = _curry2(isIn, true);\n\n/**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\nfunction _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n}\n\n/**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\nvar count = _groupWith(function (a) {\n return a ? ++a : 1;\n});\n\n/**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter([_.getKey(\"city\"), _.always(\"Unknown\")]);\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar countBy = _curry2(count, true);\n\n/**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\nfunction filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n}\n\n/**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\nfunction not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n}\n\n/**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nfunction uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n\n for (var i = 0, len = arrayLike.length, seen = [], value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n };\n}\n\n/**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nvar uniques = uniquesBy(identity);\n\n/**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.pull|pull}, {@link module:lamb.pullFrom|pullFrom}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\nfunction difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n}\n\n/**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\nfunction dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n}\n\n/**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @param {Number} n\n * @returns {Function}\n */\nvar drop = _curry2(dropFrom, true);\n\n/**\n * Gets the index of the last element satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\nfunction _getLastHitIndex (arrayLike, predicate, fromLast) {\n var idx;\n var increment;\n var len = arrayLike.length;\n\n if (fromLast) {\n idx = len - 1;\n increment = -1;\n } else {\n idx = 0;\n increment = 1;\n }\n\n while (idx >= 0 && idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx += increment;\n }\n\n return idx;\n}\n\n/**\n * Helper to build the {@link module:lamb.takeWhile|takeWhile},\n * {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropWhile|dropWhile} and\n * {@link module:lamb.dropLastWhile|dropLastWhile} functions.\n * @private\n * @param {Boolean} isTake\n * @param {Boolean} fromLast\n * @returns {Function}\n */\nfunction _takeOrDropWhile (isTake, fromLast) {\n return function (predicate) {\n return function (arrayLike) {\n var idxFrom;\n var idxTo;\n var lastHitIndex = _getLastHitIndex(arrayLike, predicate, fromLast);\n\n if (isTake && fromLast) {\n idxFrom = lastHitIndex + 1;\n idxTo = arrayLike.length;\n } else if (isTake) {\n idxFrom = 0;\n idxTo = lastHitIndex;\n } else if (!isTake && fromLast) {\n idxFrom = 0;\n idxTo = lastHitIndex + 1;\n } else {\n idxFrom = lastHitIndex;\n idxTo = arrayLike.length;\n }\n\n return slice(arrayLike, idxFrom, idxTo);\n };\n };\n}\n\n/**\n * Builds a function that drops the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropLastWhileIsEven = _.dropLastWhile(isEven);\n *\n * dropLastWhileIsEven([2, 4, 6, 8]) // => []\n * dropLastWhileIsEven([2, 4, 7, 8]) // => [2, 4, 7]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar dropLastWhile = _takeOrDropWhile(false, true);\n\n/**\n * Builds a function that drops the first elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar dropWhile = _takeOrDropWhile(false, false);\n\n/**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\nfunction _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n}\n\n/**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\nvar everyIn = _makeArrayChecker(true);\n\n/**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar every = _curry2(everyIn, true);\n\n/**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar filterWith = _curry2(filter, true);\n\n/**\n * Helper to create the {@link module:lamb.findIndex|findIndex} and\n * {@link module:lamb.findLastIndex|findLastIndex} functions.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\nfunction _findIndex (arrayLike, predicate, fromLast) {\n var start;\n var increment;\n var len = arrayLike.length;\n var result = -1;\n\n if (fromLast) {\n start = len - 1;\n increment = -1;\n } else {\n start = 0;\n increment = 1;\n }\n\n for (var i = start; i < len && i >= 0; i += increment) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\nfunction findIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, false);\n}\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\nfunction find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n}\n\n/**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 6, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findIndexWhere = _curry2(findIndex, true);\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object starting from\n * the end and returns its index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 40)) // => 3\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\nfunction findLastIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, true);\n}\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object starting from the end\n * and returns it if the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLast(persons, _.hasKeyValue(\"surname\", \"Doe\")) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.findLast(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\nfunction findLast (arrayLike, predicate) {\n var idx = findLastIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n}\n\n/**\n * A curried version of {@link module:lamb.findLastIndex|findLastIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findLastEvenIdx = _.findLastIndexWhere(isEven);\n *\n * findLastEvenIdx([1, 3, 4, 5, 6, 7]) // => 4\n * findLastEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastIndex|findLastIndex}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findLastIndexWhere = _curry2(findLastIndex, true);\n\n/**\n * A curried version of {@link module:lamb.findLast|findLast} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findLastWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 6, 7]) // => 6\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findLastWhere = _curry2(findLast, true);\n\n/**\n * A curried version of {@link module:lamb.find|find} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findWhere = _curry2(find, true);\n\n/**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\nfunction flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n}\n\n/**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar flatMapWith = _curry2(flatMap, true);\n\n/**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\nfunction _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n}\n\n/**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\nvar _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n});\n\n/**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\nvar flatten = _makeArrayFlattener(true);\n\n/**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\nfunction _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n}\n\n/**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\nfunction getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n}\n\n/**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\nvar getAt = _curry2(getIndex, true);\n\n/**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter([getCity, _.always(\"Unknown\")]);\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\nvar group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n});\n\n/**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar groupBy = _curry2(group, true);\n\n/**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\nvar head = getAt(0);\n\n/**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\nvar index = _groupWith(function (a, b) {\n return b;\n});\n\n/**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar indexBy = _curry2(index, true);\n\n/**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nvar init = partial(slice, [__, 0, -1]);\n\n/**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\nfunction insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n}\n\n/**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\nvar insertAt = _makePartial3(insert);\n\n/**\n * Returns an array of every unique item that is included in all two given arrays\n * or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\nfunction intersection (a, b) {\n var result = [];\n var lenA = a.length;\n\n if (lenA && b.length) {\n for (var i = 0; i < lenA; i++) {\n !isIn(result, a[i]) && isIn(b, a[i]) && result.push(a[i]);\n }\n }\n\n return result;\n}\n\n/**\n * Transforms an array-like object into a string by joining its elements with\n * the given separator.
\n * Note that unlike the native method, this function won't convert\n * null and undefined values in the array to empty\n * strings and that the separator parameter isn't optional.
\n * See the examples about these differences.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n *\n * _.join(words, \"-\") // => \"foo-bar-baz\"\n *\n * @example Showing the differences with the native array method:\n * var mixed = [1, null, 2, undefined, 3, NaN, 4, 5];\n * var numbers = [1, 2, 3];\n *\n * _.join(mixed, \"-\") // => \"1-null-2-undefined-3-NaN-4-5\"\n * mixed.join(\"-\") // => \"1--2--3-NaN-4-5\"\n *\n * _.join(numbers) // => \"1undefined2undefined3\"\n * numbers.join() // => \"1,2,3\"\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.joinWith|joinWith}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {String} separator\n * @returns {String}\n */\nfunction join (arrayLike, separator) {\n return map(arrayLike, String).join(String(separator));\n}\n\n/**\n * A curried version of {@link module:lamb.join|join} that accepts an optional\n * separator and builds a function expecting the array-like object to act upon.
\n * Please refer to the description and examples of {@link module:lamb.join|join}\n * to understand the differences with the native array method.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n * var joinWithDash = _.joinWith(\"-\");\n *\n * joinWithDash(words) // => \"foo-bar-baz\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.join|join}\n * @since 0.58.0\n * @param {String} separator\n * @returns {Function}\n */\nvar joinWith = _curry2(join, true);\n\n/**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\nvar last = getAt(-1);\n\n/**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\nfunction _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n}\n\n/**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\nvar list = _argsToArrayFrom(0);\n\n/**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\nfunction partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar partitionWith = _curry2(partition, true);\n\n/**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\nfunction getIn (obj, key) {\n return obj[key];\n}\n\n/**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\nvar getKey = _curry2(getIn, true);\n\n/**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\nfunction pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n}\n\n/**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\nvar pluckKey = compose(mapWith, getKey);\n\n/**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @example It's not the same as {@link module:lamb.difference|difference}:\n *\n * var arr = [1,1,2,3,4,4,5];\n *\n * _.pullFrom(arr, [1, 2]) // => [3, 4, 4, 5]\n * _.difference(arr, [1, 2]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\nfunction pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n}\n\n/**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * See examples in {@link module:lamb.pullFrom|pullFrom} about the\n * relationship with {@link module:lamb.difference|difference}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\nvar pull = _curry2(pullFrom, true);\n\n/**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\nvar reduceRight = _makeReducer(-1);\n\n/**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\nvar reduceRightWith = _makePartial3(reduceRight, true);\n\n/**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nfunction reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n}\n\n/**\n * Returns a copy of the given array-like with the element rotated by the desired amount.\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.rotate(arr, 3) // => [3, 4, 5, 1, 2]\n * _.rotate(arr, -3) // => [4, 5, 1, 2, 3]\n * _.rotate(arr, 11) // => [5, 1, 2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.rotateBy|rotateBy}\n * @since 0.55.0\n * @param {ArrayLike} arrayLike\n * @param {Number} amount\n * @returns {Array}\n */\nfunction rotate (arrayLike, amount) {\n var len = arrayLike.length;\n var shift = amount % len;\n\n return slice(arrayLike, -shift, len).concat(slice(arrayLike, 0, -shift));\n}\n\n/**\n * A curried version of {@link module:lamb.rotate|rotate}.
\n * Uses the given amount to build a function expecting the array to rotate by that amount.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var rotateByTwo = _.rotateBy(2);\n *\n * rotateByTwo(arr) // => [4, 5, 1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.rotate|rotate}\n * @since 0.55.0\n * @param {Number} amount\n * @returns {Function}\n */\nvar rotateBy = _curry2(rotate, true);\n\n/**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\nfunction _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\nvar setAt = _makePartial3(_setIndex);\n\n/**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\nfunction aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n}\n\n/**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\nvar setIndex = aritize(_setIndex, 3);\n\n/**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\nvar shallowFlatten = _makeArrayFlattener(false);\n\n/**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\nvar someIn = _makeArrayChecker(false);\n\n/**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar some = _curry2(someIn, true);\n\n/**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\nfunction _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n}\n\n/**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\nfunction _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n if (!areSVZ(a, b)) {\n // eslint-disable-next-line no-self-compare\n result = a > b || a !== a ? 1 : -1;\n }\n\n return result;\n}\n\n/**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\nfunction _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n}\n\n/**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\nfunction _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n}\n\n/**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\nfunction _makeCriteria (sorters) {\n return sorters && sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n}\n\n/**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, [_.getKey(\"name\")]);\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(persons, [\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * ]);\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, [localeSorter]) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, [localeSorterDesc]) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Array}\n */\nfunction sort (arrayLike, sorters) {\n var criteria = _makeCriteria(sorters);\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = { value: arrayLike[i], index: i };\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n}\n\n/**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\nfunction _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n { value: element, index: pivot },\n { value: array[pivot], index: pivot }\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n}\n\n/**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\nfunction sortedInsert (arrayLike, element, sorters) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n}\n\n/**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\nvar sorter = partial(_sorter, [__, false, __]);\n\n/**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\nvar sorterDesc = partial(_sorter, [__, true, __]);\n\n/**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith([parseFloat]);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Function}\n */\nvar sortWith = _curry2(sort, true);\n\n/**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nvar tail = drop(1);\n\n/**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\nfunction takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n}\n\n/**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\nvar take = _curry2(takeFrom, true);\n\n/**\n * Builds a function that takes the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeLastWhileIsEven = _.takeLastWhile(isEven);\n *\n * takeLastWhileIsEven([1, 3, 5, 7]) // => []\n * takeLastWhileIsEven([2, 3, 6, 8]) // => [6, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar takeLastWhile = _takeOrDropWhile(true, true);\n\n/**\n * Builds a function that takes the first elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar takeWhile = _takeOrDropWhile(true, false);\n\n/**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nfunction transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n}\n\n/**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\nfunction _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n}\n\n/**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var __ = _.__;\n * var square = _.partial(Math.pow, [__, 2]);\n * var getMaxAndSquare = _.pipe([Math.max, square]);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {Function[]} functions\n * @returns {Function}\n */\nfunction pipe (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n var len = functions.length;\n\n return len ? function () {\n var result = functions[0].apply(this, arguments);\n\n for (var i = 1; i < len; i++) {\n result = functions[i].call(this, result);\n }\n\n return result;\n } : identity;\n}\n\n/**\n * Using the provided iteratee to transform values, builds a function that will\n * return an array of the unique elements in the two provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to compare transformed values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nfunction unionBy (iteratee) {\n return pipe([binary(list), flatMapWith(drop(0)), uniquesBy(iteratee)]);\n}\n\n/**\n * Returns a list of every unique element present in the two given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [2, 3, 4]) // => [1, 2, 3, 4]\n * _.union(\"abc\", \"bcd\") // => [\"a\", \"b\", \"c\", \"d\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\nvar union = unionBy(identity);\n\n/**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\nfunction updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n}\n\n/**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\nvar updateIndex = partial(_setIndex, [__, __, null, __]);\n\n/**\n * Builds a list of arrays out of the two given array-like objects by pairing items with\n * the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3]\n * ) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\nfunction zip (a, b) {\n return transpose([a, b]);\n}\n\n/**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\nvar zipWithIndex = mapWith(binary(list));\n\n/**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\nfunction application (fn, args) {\n return fn.apply(this, Object(args));\n}\n\n/**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\nvar apply = _curry2(application);\n\n/**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\nvar applyTo = _curry2(application, true);\n\n/**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\nfunction _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === __ && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === __) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === __) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n}\n\n/**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, __, 2)(3) // => 9\n * f(__, 3, __)(4, __)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, __);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, __);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction asPartial (fn) {\n return _asPartial(fn, []);\n}\n\n/**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect([_.getKey(\"id\"), _.getPath(\"scores.-1\")]);\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect([Math.min, Math.max]);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {Function[]} functions\n * @returns {Function}\n */\nfunction collect (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n}\n\n/**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\nfunction _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n}\n\n/**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\nfunction _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n}\n\n/**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\nfunction _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n}\n\n/**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curry (fn, arity) {\n return _curry(fn, arity, false);\n}\n\n/**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n}\n\n/**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n}\n\n/**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curryRight (fn, arity) {\n return _curry(fn, arity, true);\n}\n\n/**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\nfunction debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n}\n\n/**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n}\n\n/**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = _.getArgAt(0);\n * var getLastArg = _.getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * _.getArgAt()(1, 2, 3) // => undefined\n * _.getArgAt(6)(1, 2, 3) // => undefined\n * _.getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\nfunction getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n}\n\n/* eslint-disable jsdoc/check-param-names */\n\n/**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * received by {@link module:lamb.invoker|invoker}, with the final set of args,\n * if present.\n * @private\n * @param {String} methodName\n * @param {Array} boundArgs\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\nfunction _invoker (methodName, boundArgs, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs ? _toArrayLength(boundArgs.length) : 0;\n var finalArgsLen = boundArgsLen + arguments.length - 3;\n var finalArgs = Array(finalArgsLen);\n\n for (var i = 0; i < boundArgsLen; i++) {\n finalArgs[i] = boundArgs[i];\n }\n\n for (var ofs = 3 - i; i < finalArgsLen; i++) {\n finalArgs[i] = arguments[i + ofs];\n }\n\n return method.apply(target, finalArgs);\n}\n\n/**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", [2]);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {ArrayLike} [boundArgs=[]]\n * @returns {Function}\n */\nfunction invoker (methodName, boundArgs) {\n return partial(_invoker, [methodName, boundArgs]);\n}\n\n/**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\nfunction invokerOn (target) {\n return partial(_invoker, [__, [], target]);\n}\n\n/**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var __ = _.__;\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [__, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\nfunction mapArgs (fn, mapper) {\n return pipe([list, mapWith(mapper), apply(fn)]);\n}\n\n/**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\nfunction tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n}\n\n/**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\nfunction throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n}\n\n/**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n}\n\n/**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in synergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.invoker(\"join\", [\"\"]), _.filter);\n * var filterAdapter = _.adapter([\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * ]);\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // by its nature is composable\n * var filterWithDefault = _.adapter([filterAdapter, _.always(\"Not implemented\")]);\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {Function[]} functions\n * @returns {Function}\n */\nfunction adapter (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n}\n\n/**\n * Creates a function to check the given predicates.
\n * Used to build the {@link module:lamb.allOf|allOf} and the\n * {@link module:lamb.anyOf|anyOf} functions.\n * @private\n * @param {Boolean} checkAll\n * @returns {Function}\n */\nfunction _checkPredicates (checkAll) {\n return function (predicates) {\n if (!Array.isArray(predicates)) {\n throw _makeTypeErrorFor(predicates, \"array\");\n }\n\n return function () {\n for (var i = 0, len = predicates.length, result; i < len; i++) {\n result = predicates[i].apply(this, arguments);\n\n if (checkAll && !result) {\n return false;\n } else if (!checkAll && result) {\n return true;\n }\n }\n\n return checkAll;\n };\n };\n}\n\n/**\n * Accepts an array of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the array will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf([isEven, _.isGT(0)]);\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\nvar allOf = _checkPredicates(true);\n\n/**\n * Accepts an array of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the array will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf([isInGroup(\"admin\"), isInGroup(\"root\")]);\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\nvar anyOf = _checkPredicates(false);\n\n/**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\nfunction areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n}\n\n/**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions\n * and {@link module:lamb.unless|unless} and {@link module:lamb.when|when} where one of the branches\n * is the identity function.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @alias module:lamb.case\n * @category Logic\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\nfunction case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n}\n\n/**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\nfunction condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n}\n\n/**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction gt (a, b) {\n return a > b;\n}\n\n/**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction gte (a, b) {\n return a >= b;\n}\n\n/**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\nvar is = _curry2(areSame);\n\n/**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isGT = _curry2(gt, true);\n\n/**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isGTE = _curry2(gte, true);\n\n/**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction lt (a, b) {\n return a < b;\n}\n\n/**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isLT = _curry2(lt, true);\n\n/**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction lte (a, b) {\n return a <= b;\n}\n\n/**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isLTE = _curry2(lte, true);\n\n/**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\nfunction unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n}\n\n/**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\nfunction when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n}\n\n/**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction sum (a, b) {\n return a + b;\n}\n\n/**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\nvar add = _curry2(sum, true);\n\n/**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction subtract (a, b) {\n return a - b;\n}\n\n/**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\nvar deduct = _curry2(subtract, true);\n\n/**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction divide (a, b) {\n return a / b;\n}\n\n/**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\nvar divideBy = _curry2(divide, true);\n\n/**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\nfunction generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n}\n\n/**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @alias module:lamb.isFinite\n * @category Math\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n}\n\n/**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n}\n\n/**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction modulo (a, b) {\n return a - (b * Math.floor(a / b));\n}\n\n/**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction multiply (a, b) {\n return a * b;\n}\n\n/**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\nvar multiplyBy = _curry2(multiply, true);\n\n/**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\nfunction randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n}\n\n/**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\nfunction _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n}\n\n/**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\nfunction range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n}\n\n/**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction remainder (a, b) {\n return a % b;\n}\n\n/**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nvar _isOwnEnumerable = generic(Object.prototype.propertyIsEnumerable);\n\n/**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\nfunction _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n}\n\n/**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nfunction _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n}\n\n/**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\nfunction _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n}\n\n/**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\nfunction _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? { isValid: true, target: target } : { isValid: false, target: void 0 };\n}\n\n/**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\nfunction _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n}\n\n/**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\nfunction getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n}\n\n/**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.areSame,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\nfunction checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, __, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n}\n\n/**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n});\n\n/**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\nvar enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n/**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\nfunction fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n}\n\n/**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nvar getPath = _makePartial3(getPathIn);\n\n/**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nfunction has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n}\n\n/**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\nvar hasKey = _curry2(has, true);\n\n/**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nvar hasOwn = generic(Object.prototype.hasOwnProperty);\n\n/**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\nvar hasOwnKey = _curry2(hasOwn, true);\n\n/**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\nfunction hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n}\n\n/**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n}\n\n/**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\nvar _safeKeys = compose(Object.keys, Object);\n\n/**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\nvar keys = _unsafeKeyListFrom(_safeKeys);\n\n/**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\nfunction keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n}\n\n/**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\nfunction make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n}\n\n/**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\nfunction mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\nvar mapValuesWith = _curry2(mapValues, true);\n\n/**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {Object} a\n * @param {Object} b\n * @returns {Function}\n */\nfunction _merge (getKeys, a, b) {\n return reduce([a, b], function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n}\n\n/**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy the last source has precedence over the first.\n * @example\n * _.merge({a: 1, b: 3}, {b: 5, c: 4}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99) // => {a: 2}\n * _.merge({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\nvar merge = partial(_merge, [enumerables]);\n\n/**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99) // => {a: 2}\n * _.mergeOwn({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\nvar mergeOwn = partial(_merge, [keys]);\n\n/**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\nvar _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n});\n\n/**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n});\n\n/**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\nvar ownPairs = _pairsFrom(keys);\n\n/**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), function (key) {\n return obj[key];\n });\n});\n\n/**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar ownValues = _valuesFrom(keys);\n\n/**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\nvar pairs = _pairsFrom(enumerables);\n\n/**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\nfunction pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n}\n\n/**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nvar pathExists = _makePartial3(pathExistsIn);\n\n/**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n}\n\n/**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\nfunction pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n\n/**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\nfunction pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n}\n\n/**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\nvar pickKeys = _curry2(pick, true);\n\n/**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\nfunction rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\nvar renameKeys = _curry2(rename, true);\n\n/**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n}\n\n/**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\nfunction _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n}\n\n/**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\nfunction setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n}\n\n/**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\nvar setKey = _makePartial3(setIn);\n\n/**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\nfunction _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n}\n\n/**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\nfunction _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n}\n\n/**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\nfunction setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n}\n\n/**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n}\n\n/**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\nfunction skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n\n/**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\nvar skipIf = compose(pickIf, not);\n\n/**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\nvar skipKeys = _curry2(skip, true);\n\n/**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n});\n\n/**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar tear = _tearFrom(enumerables);\n\n/**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar tearOwn = _tearFrom(keys);\n\n/**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\nfunction updateIn (source, key, updater) {\n return _isEnumerable(source, key)\n ? _setIn(source, key, updater(source[key]))\n : _merge(enumerables, source, {});\n}\n\n/**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\nvar updateKey = _makePartial3(updateIn);\n\n/**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\nfunction updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source, {});\n }\n}\n\n/**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n}\n\n/**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\nfunction validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n}\n\n/**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\nvar validateWith = _curry2(validate, true);\n\n/**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar values = _valuesFrom(enumerables);\n\n/**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\nfunction _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n}\n\n/**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\nfunction _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n}\n\n/**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\nfunction padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n}\n\n/**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\nfunction padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n}\n\n/**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\nfunction repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n}\n\n/**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\nvar _search = generic(String.prototype.search);\n\n/**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\nfunction testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n}\n\n/**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\nfunction isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n}\n\n/**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\nfunction isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n}\n\nexport { __, adapter, add, allOf, always, anyOf, append, appendTo, application, apply, applyTo, areSVZ, areSame, aritize, asPartial, binary, case_ as case, checker, clamp, clampWithin, collect, compose, condition, contains, count, countBy, curry, curryRight, curryable, curryableRight, debounce, deduct, difference, divide, divideBy, drop, dropFrom, dropLastWhile, dropWhile, enumerables, every, everyIn, filter, filterWith, find, findIndex, findIndexWhere, findLast, findLastIndex, findLastIndexWhere, findLastWhere, findWhere, flatMap, flatMapWith, flatten, flip, forEach, fromPairs, generate, generic, getArgAt, getAt, getIn, getIndex, getKey, getPath, getPathIn, group, groupBy, gt, gte, has, hasKey, hasKeyValue, hasOwn, hasOwnKey, hasPathValue, head, identity, index, indexBy, init, insert, insertAt, intersection, invoker, invokerOn, is, isFinite_ as isFinite, isGT, isGTE, isIn, isInstanceOf, isInteger, isLT, isLTE, isNil, isNull, isSVZ, isSafeInteger, isType, isUndefined, join, joinWith, keySatisfies, keys, last, list, lt, lte, make, map, mapArgs, mapValues, mapValuesWith, mapWith, merge, mergeOwn, modulo, multiply, multiplyBy, not, ownPairs, ownValues, padLeft, padRight, pairs, partial, partialRight, partition, partitionWith, pathExists, pathExistsIn, pathSatisfies, pick, pickIf, pickKeys, pipe, pluck, pluckKey, pull, pullFrom, randomInt, range, reduce, reduceRight, reduceRightWith, reduceWith, remainder, rename, renameKeys, renameWith, repeat, reverse, rotate, rotateBy, setAt, setIn, setIndex, setKey, setPath, setPathIn, shallowFlatten, skip, skipIf, skipKeys, slice, sliceAt, some, someIn, sort, sortWith, sortedInsert, sorter, sorterDesc, subtract, sum, tail, take, takeFrom, takeLastWhile, takeWhile, tapArgs, tear, tearOwn, testWith, throttle, transpose, type, unary, union, unionBy, uniques, uniquesBy, unless, updateAt, updateIn, updateIndex, updateKey, updatePath, updatePathIn, validate, validateWith, values, when, zip, zipWithIndex };\n"]} \ No newline at end of file +{"version":3,"sources":["lamb.esm.js"],"names":["__","always","value","areSVZ","a","b","binary","fn","call","this","clamp","n","min","max","NaN","partial","args","Array","isArray","apply","arguments","boundArg","lastIdx","newArgs","argsLen","length","i","len","_makePartial3","shouldAritize","clampWithin","identity","compose","MAX_ARRAY_LENGTH","MAX_SAFE_INTEGER","_toArrayLength","forEach","arrayLike","iteratee","generic","Function","bind","isNull","isUndefined","isNil","_curry2","isRightCurry","isSVZ","map","result","mapWith","partialRight","boundArgs","j","_makeReducer","step","accumulator","initialValue","nCalls","idx","TypeError","reduce","reduceWith","_toInteger","Math","floor","abs","slice","start","end","begin","upTo","resultLen","sliceAt","objectProtoToString","Object","prototype","toString","type","appendTo","concat","append","isIn","contains","_groupWith","makeValue","element","key","count","countBy","filter","predicate","push","not","uniquesBy","seen","uniques","difference","other","isNotInOther","dropFrom","drop","_getLastHitIndex","fromLast","increment","_takeOrDropWhile","isTake","idxFrom","idxTo","lastHitIndex","dropLastWhile","dropWhile","_makeArrayChecker","defaultResult","everyIn","every","filterWith","_findIndex","findIndex","find","findIndexWhere","findLastIndex","findLast","findLastIndexWhere","findLastWhere","findWhere","flatMap","array","el","arr","v","rLen","flatMapWith","_flatten","isDeep","output","vLen","_makeArrayFlattener","flatten","_toNaturalIndex","getIndex","index","getAt","group","groupBy","head","indexBy","init","insert","splice","insertAt","intersection","lenA","join","separator","String","joinWith","last","_argsToArrayFrom","list","partition","partitionWith","getIn","obj","getKey","pluck","pluckKey","pullFrom","values","pull","reduceRight","reduceRightWith","reverse","ofs","rotate","amount","shift","rotateBy","_setIndex","updater","setAt","aritize","arity","setIndex","shallowFlatten","someIn","some","_compareWith","criteria","criterion","compare","isDescending","_comparer","_sorter","reader","comparer","_makeCriterion","_makeCriteria","sorters","sort","_getInsertionIndex","pivot","sortedInsert","sorter","sorterDesc","sortWith","tail","takeFrom","take","takeLastWhile","takeWhile","transpose","minLen","elementLen","_makeTypeErrorFor","desiredType","toLowerCase","pipe","functions","unionBy","union","updateAt","updateIndex","zip","zipWithIndex","application","applyTo","_asPartial","argsHolder","asPartial","collect","_currier","isAutoCurry","holderLen","newArgsLen","_curry3","c","_curry","curry","curryable","curryableRight","curryRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","flip","getArgAt","_invoker","methodName","target","method","boundArgsLen","finalArgsLen","finalArgs","invoker","invokerOn","mapArgs","mapper","tapArgs","tappers","tappersLen","throttle","lastCall","now","Date","unary","adapter","_checkPredicates","checkAll","predicates","allOf","anyOf","areSame","case_","condition","trueFn","falseFn","gt","gte","is","isGT","isGTE","lt","isLT","lte","isLTE","unless","when","sum","add","subtract","deduct","divide","divideBy","generate","limit","isFinite_","isFinite","isInteger","isSafeInteger","modulo","multiply","multiplyBy","randomInt","random","_forceToNumber","range","ceil","remainder","_isOwnEnumerable","propertyIsEnumerable","_safeEnumerables","_isEnumerable","indexOf","_getPathKey","includeNonEnumerables","_getPathInfo","parts","walkNonEnumerables","isValid","_toPathParts","path","split","getPathIn","checker","message","keyPaths","pathSeparator","getValues","_unsafeKeyListFrom","getKeys","enumerables","fromPairs","pairsList","pair","getPath","has","hasKey","hasOwn","hasOwnProperty","hasOwnKey","hasKeyValue","hasPathValue","pathInfo","_safeKeys","keys","keySatisfies","make","names","valuesLen","mapValues","source","mapValuesWith","_merge","merge","mergeOwn","_keyToPairIn","_pairsFrom","ownPairs","_valuesFrom","ownValues","pairs","pathExistsIn","pathExists","pathSatisfies","pick","whitelist","pickIf","pickKeys","rename","keysMap","oldKeys","prop","renameKeys","renameWith","_setIn","setIn","setKey","_isArrayIndex","_setPathIn","partsLen","targetKey","setPathIn","setPath","skip","blacklist","props","skipIf","skipKeys","_tearFrom","tear","tearOwn","updateIn","updateKey","updatePathIn","updatePath","validate","checkers","errors","_checker","validateWith","_repeat","times","_getPadding","char","padLeft","padRight","repeat","_search","search","testWith","pattern","s","isInstanceOf","constructor","isType","typeName"],"mappings":"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","file":"lamb.esm.min.js","sourcesContent":["/**\n* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n* @author Andrea Scartabelli \n* @version 0.58.0\n* @module lamb\n* @license MIT\n*/\n/**\n * The placeholder object used in partial application.\n * @memberof module:lamb\n * @alias module:lamb.__\n * @category Special properties\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.57.0\n * @type {Object}\n */\nvar __ = {};\n\n/**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\nfunction always (value) {\n return function () {\n return value;\n };\n}\n\n/**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\nfunction areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n}\n\n/**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n}\n\n/**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\nfunction clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n}\n\n/**\n * Builds a partially applied function.
\n * The {@link module:lamb.__|__} object can be used as a placeholder for arguments.
\n * @example\n * var __ = _.__;\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [__, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\nfunction partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = boundArg === __ ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n}\n\n/**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\nfunction _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [__, a, b]);\n };\n}\n\n/**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\nvar clampWithin = _makePartial3(clamp);\n\n/**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\nfunction identity (value) {\n return value;\n}\n\n/**\n * Returns a function that is the composition of the functions given as parameters.\n * The first function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {Function} a\n * @param {Function} b\n * @returns {Function}\n */\nfunction compose (a, b) {\n return arguments.length ? function () {\n return a.call(this, b.apply(this, arguments));\n } : identity;\n}\n\nvar MAX_ARRAY_LENGTH = 4294967295;\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\nfunction _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n}\n\n/* eslint-disable jsdoc/require-returns-check */\n\n/**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\nfunction forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n}\n\n/**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\nvar generic = Function.bind.bind(Function.call);\n\n/**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isNull (value) {\n return value === null;\n}\n\n/**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isUndefined (value) {\n return value === void 0;\n}\n\n/**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isNil (value) {\n return isNull(value) || isUndefined(value);\n}\n\n/**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\nfunction _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n}\n\n/**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\nvar isSVZ = _curry2(areSVZ);\n\n/**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\nfunction map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\nvar mapWith = _curry2(map, true);\n\n/**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var __ = _.__;\n * var f1 = _.partial(_.list, [\"a\", __, __, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", __, __, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\nfunction partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = boundArg === __ ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n}\n\n/**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\nfunction _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n}\n\n/**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\nvar reduce = _makeReducer(1);\n\n/**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\nvar reduceWith = _makePartial3(reduce, true);\n\n/**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\nfunction _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n}\n\n/**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\nfunction slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n}\n\n/**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\nvar sliceAt = _makePartial3(slice);\n\nvar objectProtoToString = Object.prototype.toString;\n\n/**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\nfunction type (value) {\n return objectProtoToString.call(value).slice(8, -1);\n}\n\n/**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\nfunction appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n}\n\n/**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\nvar append = _curry2(appendTo, true);\n\n/**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\nvar contains = _curry2(isIn, true);\n\n/**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\nfunction _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n}\n\n/**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\nvar count = _groupWith(function (a) {\n return a ? ++a : 1;\n});\n\n/**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter([_.getKey(\"city\"), _.always(\"Unknown\")]);\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar countBy = _curry2(count, true);\n\n/**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\nfunction filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n}\n\n/**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\nfunction not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n}\n\n/**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nfunction uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n\n for (var i = 0, len = arrayLike.length, seen = [], value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n };\n}\n\n/**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nvar uniques = uniquesBy(identity);\n\n/**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.pull|pull}, {@link module:lamb.pullFrom|pullFrom}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\nfunction difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n}\n\n/**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\nfunction dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n}\n\n/**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @param {Number} n\n * @returns {Function}\n */\nvar drop = _curry2(dropFrom, true);\n\n/**\n * Gets the index of the last element satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\nfunction _getLastHitIndex (arrayLike, predicate, fromLast) {\n var idx;\n var increment;\n var len = arrayLike.length;\n\n if (fromLast) {\n idx = len - 1;\n increment = -1;\n } else {\n idx = 0;\n increment = 1;\n }\n\n while (idx >= 0 && idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx += increment;\n }\n\n return idx;\n}\n\n/**\n * Helper to build the {@link module:lamb.takeWhile|takeWhile},\n * {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropWhile|dropWhile} and\n * {@link module:lamb.dropLastWhile|dropLastWhile} functions.\n * @private\n * @param {Boolean} isTake\n * @param {Boolean} fromLast\n * @returns {Function}\n */\nfunction _takeOrDropWhile (isTake, fromLast) {\n return function (predicate) {\n return function (arrayLike) {\n var idxFrom;\n var idxTo;\n var lastHitIndex = _getLastHitIndex(arrayLike, predicate, fromLast);\n\n if (isTake && fromLast) {\n idxFrom = lastHitIndex + 1;\n idxTo = arrayLike.length;\n } else if (isTake) {\n idxFrom = 0;\n idxTo = lastHitIndex;\n } else if (!isTake && fromLast) {\n idxFrom = 0;\n idxTo = lastHitIndex + 1;\n } else {\n idxFrom = lastHitIndex;\n idxTo = arrayLike.length;\n }\n\n return slice(arrayLike, idxFrom, idxTo);\n };\n };\n}\n\n/**\n * Builds a function that drops the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropLastWhileIsEven = _.dropLastWhile(isEven);\n *\n * dropLastWhileIsEven([2, 4, 6, 8]) // => []\n * dropLastWhileIsEven([2, 4, 7, 8]) // => [2, 4, 7]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar dropLastWhile = _takeOrDropWhile(false, true);\n\n/**\n * Builds a function that drops the first elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar dropWhile = _takeOrDropWhile(false, false);\n\n/**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\nfunction _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n}\n\n/**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\nvar everyIn = _makeArrayChecker(true);\n\n/**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar every = _curry2(everyIn, true);\n\n/**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar filterWith = _curry2(filter, true);\n\n/**\n * Helper to create the {@link module:lamb.findIndex|findIndex} and\n * {@link module:lamb.findLastIndex|findLastIndex} functions.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\nfunction _findIndex (arrayLike, predicate, fromLast) {\n var start;\n var increment;\n var len = arrayLike.length;\n var result = -1;\n\n if (fromLast) {\n start = len - 1;\n increment = -1;\n } else {\n start = 0;\n increment = 1;\n }\n\n for (var i = start; i < len && i >= 0; i += increment) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\nfunction findIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, false);\n}\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\nfunction find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n}\n\n/**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 6, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findIndexWhere = _curry2(findIndex, true);\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object starting from\n * the end and returns its index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 40)) // => 3\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\nfunction findLastIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, true);\n}\n\n/**\n * Searches for an element satisfying the predicate in the given array-like object starting from the end\n * and returns it if the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLast(persons, _.hasKeyValue(\"surname\", \"Doe\")) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.findLast(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\nfunction findLast (arrayLike, predicate) {\n var idx = findLastIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n}\n\n/**\n * A curried version of {@link module:lamb.findLastIndex|findLastIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findLastEvenIdx = _.findLastIndexWhere(isEven);\n *\n * findLastEvenIdx([1, 3, 4, 5, 6, 7]) // => 4\n * findLastEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastIndex|findLastIndex}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findLastIndexWhere = _curry2(findLastIndex, true);\n\n/**\n * A curried version of {@link module:lamb.findLast|findLast} that uses the given\n * predicate to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findLastWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 6, 7]) // => 6\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findLastWhere = _curry2(findLast, true);\n\n/**\n * A curried version of {@link module:lamb.find|find} that uses the given\n * predicate to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar findWhere = _curry2(find, true);\n\n/**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\nfunction flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n}\n\n/**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar flatMapWith = _curry2(flatMap, true);\n\n/**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\nfunction _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n}\n\n/**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\nvar _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n});\n\n/**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\nvar flatten = _makeArrayFlattener(true);\n\n/**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\nfunction _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n}\n\n/**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\nfunction getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n}\n\n/**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\nvar getAt = _curry2(getIndex, true);\n\n/**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter([getCity, _.always(\"Unknown\")]);\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\nvar group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n});\n\n/**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar groupBy = _curry2(group, true);\n\n/**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\nvar head = getAt(0);\n\n/**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\nvar index = _groupWith(function (a, b) {\n return b;\n});\n\n/**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nvar indexBy = _curry2(index, true);\n\n/**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nvar init = partial(slice, [__, 0, -1]);\n\n/**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\nfunction insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n}\n\n/**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\nvar insertAt = _makePartial3(insert);\n\n/**\n * Returns an array of every unique item that is included in all two given arrays\n * or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\nfunction intersection (a, b) {\n var result = [];\n var lenA = a.length;\n\n if (lenA && b.length) {\n for (var i = 0; i < lenA; i++) {\n !isIn(result, a[i]) && isIn(b, a[i]) && result.push(a[i]);\n }\n }\n\n return result;\n}\n\n/**\n * Transforms an array-like object into a string by joining its elements with\n * the given separator.
\n * Note that unlike the native method, this function won't convert\n * null and undefined values in the array to empty\n * strings and that the separator parameter isn't optional.
\n * See the examples about these differences.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n *\n * _.join(words, \"-\") // => \"foo-bar-baz\"\n *\n * @example Showing the differences with the native array method:\n * var mixed = [1, null, 2, undefined, 3, NaN, 4, 5];\n * var numbers = [1, 2, 3];\n *\n * _.join(mixed, \"-\") // => \"1-null-2-undefined-3-NaN-4-5\"\n * mixed.join(\"-\") // => \"1--2--3-NaN-4-5\"\n *\n * _.join(numbers) // => \"1undefined2undefined3\"\n * numbers.join() // => \"1,2,3\"\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.joinWith|joinWith}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {String} separator\n * @returns {String}\n */\nfunction join (arrayLike, separator) {\n return map(arrayLike, String).join(String(separator));\n}\n\n/**\n * A curried version of {@link module:lamb.join|join} that accepts an optional\n * separator and builds a function expecting the array-like object to act upon.
\n * Please refer to the description and examples of {@link module:lamb.join|join}\n * to understand the differences with the native array method.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n * var joinWithDash = _.joinWith(\"-\");\n *\n * joinWithDash(words) // => \"foo-bar-baz\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.join|join}\n * @since 0.58.0\n * @param {String} separator\n * @returns {Function}\n */\nvar joinWith = _curry2(join, true);\n\n/**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\nvar last = getAt(-1);\n\n/**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\nfunction _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n}\n\n/**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\nvar list = _argsToArrayFrom(0);\n\n/**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\nfunction partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar partitionWith = _curry2(partition, true);\n\n/**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\nfunction getIn (obj, key) {\n return obj[key];\n}\n\n/**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\nvar getKey = _curry2(getIn, true);\n\n/**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\nfunction pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n}\n\n/**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\nvar pluckKey = compose(mapWith, getKey);\n\n/**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @example It's not the same as {@link module:lamb.difference|difference}:\n *\n * var arr = [1,1,2,3,4,4,5];\n *\n * _.pullFrom(arr, [1, 2]) // => [3, 4, 4, 5]\n * _.difference(arr, [1, 2]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\nfunction pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n}\n\n/**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * See examples in {@link module:lamb.pullFrom|pullFrom} about the\n * relationship with {@link module:lamb.difference|difference}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\nvar pull = _curry2(pullFrom, true);\n\n/**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\nvar reduceRight = _makeReducer(-1);\n\n/**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\nvar reduceRightWith = _makePartial3(reduceRight, true);\n\n/**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nfunction reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n}\n\n/**\n * Returns a copy of the given array-like with the element rotated by the desired amount.\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.rotate(arr, 3) // => [3, 4, 5, 1, 2]\n * _.rotate(arr, -3) // => [4, 5, 1, 2, 3]\n * _.rotate(arr, 11) // => [5, 1, 2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.rotateBy|rotateBy}\n * @since 0.55.0\n * @param {ArrayLike} arrayLike\n * @param {Number} amount\n * @returns {Array}\n */\nfunction rotate (arrayLike, amount) {\n var len = arrayLike.length;\n var shift = amount % len;\n\n return slice(arrayLike, -shift, len).concat(slice(arrayLike, 0, -shift));\n}\n\n/**\n * A curried version of {@link module:lamb.rotate|rotate}.
\n * Uses the given amount to build a function expecting the array to rotate by that amount.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var rotateByTwo = _.rotateBy(2);\n *\n * rotateByTwo(arr) // => [4, 5, 1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.rotate|rotate}\n * @since 0.55.0\n * @param {Number} amount\n * @returns {Function}\n */\nvar rotateBy = _curry2(rotate, true);\n\n/**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\nfunction _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\nvar setAt = _makePartial3(_setIndex);\n\n/**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\nfunction aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n}\n\n/**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\nvar setIndex = aritize(_setIndex, 3);\n\n/**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\nvar shallowFlatten = _makeArrayFlattener(false);\n\n/**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\nvar someIn = _makeArrayChecker(false);\n\n/**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar some = _curry2(someIn, true);\n\n/**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\nfunction _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n}\n\n/**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\nfunction _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n if (!areSVZ(a, b)) {\n // eslint-disable-next-line no-self-compare\n result = a > b || a !== a ? 1 : -1;\n }\n\n return result;\n}\n\n/**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\nfunction _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n}\n\n/**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\nfunction _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n}\n\n/**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\nfunction _makeCriteria (sorters) {\n return sorters && sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n}\n\n/**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, [_.getKey(\"name\")]);\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(persons, [\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * ]);\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, [localeSorter]) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, [localeSorterDesc]) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Array}\n */\nfunction sort (arrayLike, sorters) {\n var criteria = _makeCriteria(sorters);\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = { value: arrayLike[i], index: i };\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n}\n\n/**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\nfunction _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n { value: element, index: pivot },\n { value: array[pivot], index: pivot }\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n}\n\n/**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\nfunction sortedInsert (arrayLike, element, sorters) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n}\n\n/**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\nvar sorter = partial(_sorter, [__, false, __]);\n\n/**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\nvar sorterDesc = partial(_sorter, [__, true, __]);\n\n/**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith([parseFloat]);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Function}\n */\nvar sortWith = _curry2(sort, true);\n\n/**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nvar tail = drop(1);\n\n/**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\nfunction takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n}\n\n/**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\nvar take = _curry2(takeFrom, true);\n\n/**\n * Builds a function that takes the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeLastWhileIsEven = _.takeLastWhile(isEven);\n *\n * takeLastWhileIsEven([1, 3, 5, 7]) // => []\n * takeLastWhileIsEven([2, 3, 6, 8]) // => [6, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar takeLastWhile = _takeOrDropWhile(true, true);\n\n/**\n * Builds a function that takes the first elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\nvar takeWhile = _takeOrDropWhile(true, false);\n\n/**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\nfunction transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n}\n\n/**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\nfunction _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n}\n\n/**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var __ = _.__;\n * var square = _.partial(Math.pow, [__, 2]);\n * var getMaxAndSquare = _.pipe([Math.max, square]);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {Function[]} functions\n * @returns {Function}\n */\nfunction pipe (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n var len = functions.length;\n\n return len ? function () {\n var result = functions[0].apply(this, arguments);\n\n for (var i = 1; i < len; i++) {\n result = functions[i].call(this, result);\n }\n\n return result;\n } : identity;\n}\n\n/**\n * Using the provided iteratee to transform values, builds a function that will\n * return an array of the unique elements in the two provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to compare transformed values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\nfunction unionBy (iteratee) {\n return pipe([binary(list), flatMapWith(drop(0)), uniquesBy(iteratee)]);\n}\n\n/**\n * Returns a list of every unique element present in the two given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [2, 3, 4]) // => [1, 2, 3, 4]\n * _.union(\"abc\", \"bcd\") // => [\"a\", \"b\", \"c\", \"d\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\nvar union = unionBy(identity);\n\n/**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\nfunction updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n}\n\n/**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\nvar updateIndex = partial(_setIndex, [__, __, null, __]);\n\n/**\n * Builds a list of arrays out of the two given array-like objects by pairing items with\n * the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3]\n * ) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\nfunction zip (a, b) {\n return transpose([a, b]);\n}\n\n/**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\nvar zipWithIndex = mapWith(binary(list));\n\n/**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\nfunction application (fn, args) {\n return fn.apply(this, Object(args));\n}\n\n/**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\nvar apply = _curry2(application);\n\n/**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\nvar applyTo = _curry2(application, true);\n\n/**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\nfunction _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === __ && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === __) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === __) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n}\n\n/**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, __, 2)(3) // => 9\n * f(__, 3, __)(4, __)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, __);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, __);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction asPartial (fn) {\n return _asPartial(fn, []);\n}\n\n/**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect([_.getKey(\"id\"), _.getPath(\"scores.-1\")]);\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect([Math.min, Math.max]);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {Function[]} functions\n * @returns {Function}\n */\nfunction collect (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n}\n\n/**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\nfunction _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n}\n\n/**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\nfunction _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n}\n\n/**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\nfunction _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n}\n\n/**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curry (fn, arity) {\n return _curry(fn, arity, false);\n}\n\n/**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n}\n\n/**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n}\n\n/**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\nfunction curryRight (fn, arity) {\n return _curry(fn, arity, true);\n}\n\n/**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\nfunction debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n}\n\n/**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n}\n\n/**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = _.getArgAt(0);\n * var getLastArg = _.getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * _.getArgAt()(1, 2, 3) // => undefined\n * _.getArgAt(6)(1, 2, 3) // => undefined\n * _.getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\nfunction getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n}\n\n/* eslint-disable jsdoc/check-param-names */\n\n/**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * received by {@link module:lamb.invoker|invoker}, with the final set of args,\n * if present.\n * @private\n * @param {String} methodName\n * @param {Array} boundArgs\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\nfunction _invoker (methodName, boundArgs, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs ? _toArrayLength(boundArgs.length) : 0;\n var finalArgsLen = boundArgsLen + arguments.length - 3;\n var finalArgs = Array(finalArgsLen);\n\n for (var i = 0; i < boundArgsLen; i++) {\n finalArgs[i] = boundArgs[i];\n }\n\n for (var ofs = 3 - i; i < finalArgsLen; i++) {\n finalArgs[i] = arguments[i + ofs];\n }\n\n return method.apply(target, finalArgs);\n}\n\n/**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", [2]);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {ArrayLike} [boundArgs=[]]\n * @returns {Function}\n */\nfunction invoker (methodName, boundArgs) {\n return partial(_invoker, [methodName, boundArgs]);\n}\n\n/**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\nfunction invokerOn (target) {\n return partial(_invoker, [__, [], target]);\n}\n\n/**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var __ = _.__;\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [__, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\nfunction mapArgs (fn, mapper) {\n return pipe([list, mapWith(mapper), apply(fn)]);\n}\n\n/**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\nfunction tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n}\n\n/**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\nfunction throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n}\n\n/**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n}\n\n/**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in synergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.joinWith(\"\"), _.filter);\n * var filterAdapter = _.adapter([\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * ]);\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // by its nature is composable\n * var filterWithDefault = _.adapter([filterAdapter, _.always(\"Not implemented\")]);\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {Function[]} functions\n * @returns {Function}\n */\nfunction adapter (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n}\n\n/**\n * Creates a function to check the given predicates.
\n * Used to build the {@link module:lamb.allOf|allOf} and the\n * {@link module:lamb.anyOf|anyOf} functions.\n * @private\n * @param {Boolean} checkAll\n * @returns {Function}\n */\nfunction _checkPredicates (checkAll) {\n return function (predicates) {\n if (!Array.isArray(predicates)) {\n throw _makeTypeErrorFor(predicates, \"array\");\n }\n\n return function () {\n for (var i = 0, len = predicates.length, result; i < len; i++) {\n result = predicates[i].apply(this, arguments);\n\n if (checkAll && !result) {\n return false;\n } else if (!checkAll && result) {\n return true;\n }\n }\n\n return checkAll;\n };\n };\n}\n\n/**\n * Accepts an array of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the array will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf([isEven, _.isGT(0)]);\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\nvar allOf = _checkPredicates(true);\n\n/**\n * Accepts an array of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the array will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf([isInGroup(\"admin\"), isInGroup(\"root\")]);\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\nvar anyOf = _checkPredicates(false);\n\n/**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\nfunction areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n}\n\n/**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions\n * and {@link module:lamb.unless|unless} and {@link module:lamb.when|when} where one of the branches\n * is the identity function.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @alias module:lamb.case\n * @category Logic\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\nfunction case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n}\n\n/**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\nfunction condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n}\n\n/**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction gt (a, b) {\n return a > b;\n}\n\n/**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction gte (a, b) {\n return a >= b;\n}\n\n/**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\nvar is = _curry2(areSame);\n\n/**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isGT = _curry2(gt, true);\n\n/**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isGTE = _curry2(gte, true);\n\n/**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction lt (a, b) {\n return a < b;\n}\n\n/**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isLT = _curry2(lt, true);\n\n/**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\nfunction lte (a, b) {\n return a <= b;\n}\n\n/**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\nvar isLTE = _curry2(lte, true);\n\n/**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\nfunction unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n}\n\n/**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\nfunction when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n}\n\n/**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction sum (a, b) {\n return a + b;\n}\n\n/**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\nvar add = _curry2(sum, true);\n\n/**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction subtract (a, b) {\n return a - b;\n}\n\n/**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\nvar deduct = _curry2(subtract, true);\n\n/**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction divide (a, b) {\n return a / b;\n}\n\n/**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\nvar divideBy = _curry2(divide, true);\n\n/**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\nfunction generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n}\n\n/**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @alias module:lamb.isFinite\n * @category Math\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n}\n\n/**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n}\n\n/**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\nfunction isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction modulo (a, b) {\n return a - (b * Math.floor(a / b));\n}\n\n/**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction multiply (a, b) {\n return a * b;\n}\n\n/**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\nvar multiplyBy = _curry2(multiply, true);\n\n/**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\nfunction randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n}\n\n/**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\nfunction _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n}\n\n/**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\nfunction range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n}\n\n/**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\nfunction remainder (a, b) {\n return a % b;\n}\n\n/**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nvar _isOwnEnumerable = generic(Object.prototype.propertyIsEnumerable);\n\n/**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\nfunction _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n}\n\n/**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nfunction _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n}\n\n/**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\nfunction _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n}\n\n/**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\nfunction _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? { isValid: true, target: target } : { isValid: false, target: void 0 };\n}\n\n/**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\nfunction _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n}\n\n/**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\nfunction getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n}\n\n/**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.areSame,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\nfunction checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, __, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n}\n\n/**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n});\n\n/**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\nvar enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n/**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\nfunction fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n}\n\n/**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nvar getPath = _makePartial3(getPathIn);\n\n/**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nfunction has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n}\n\n/**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\nvar hasKey = _curry2(has, true);\n\n/**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\nvar hasOwn = generic(Object.prototype.hasOwnProperty);\n\n/**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\nvar hasOwnKey = _curry2(hasOwn, true);\n\n/**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\nfunction hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n}\n\n/**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n}\n\n/**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\nvar _safeKeys = compose(Object.keys, Object);\n\n/**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\nvar keys = _unsafeKeyListFrom(_safeKeys);\n\n/**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\nfunction keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n}\n\n/**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\nfunction make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n}\n\n/**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\nfunction mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\nvar mapValuesWith = _curry2(mapValues, true);\n\n/**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {Object} a\n * @param {Object} b\n * @returns {Function}\n */\nfunction _merge (getKeys, a, b) {\n return reduce([a, b], function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n}\n\n/**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy the last source has precedence over the first.\n * @example\n * _.merge({a: 1, b: 3}, {b: 5, c: 4}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99) // => {a: 2}\n * _.merge({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\nvar merge = partial(_merge, [enumerables]);\n\n/**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99) // => {a: 2}\n * _.mergeOwn({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\nvar mergeOwn = partial(_merge, [keys]);\n\n/**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\nvar _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n});\n\n/**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n});\n\n/**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\nvar ownPairs = _pairsFrom(keys);\n\n/**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), function (key) {\n return obj[key];\n });\n});\n\n/**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar ownValues = _valuesFrom(keys);\n\n/**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\nvar pairs = _pairsFrom(enumerables);\n\n/**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\nfunction pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n}\n\n/**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nvar pathExists = _makePartial3(pathExistsIn);\n\n/**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n}\n\n/**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\nfunction pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n\n/**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\nfunction pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n}\n\n/**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\nvar pickKeys = _curry2(pick, true);\n\n/**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\nfunction rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n\n/**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\nvar renameKeys = _curry2(rename, true);\n\n/**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\nfunction renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n}\n\n/**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\nfunction _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n}\n\n/**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\nfunction setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n}\n\n/**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\nvar setKey = _makePartial3(setIn);\n\n/**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\nfunction _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n}\n\n/**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\nfunction _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n}\n\n/**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\nfunction setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n}\n\n/**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n}\n\n/**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\nfunction skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n\n/**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\nvar skipIf = compose(pickIf, not);\n\n/**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\nvar skipKeys = _curry2(skip, true);\n\n/**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\nvar _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n});\n\n/**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar tear = _tearFrom(enumerables);\n\n/**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar tearOwn = _tearFrom(keys);\n\n/**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\nfunction updateIn (source, key, updater) {\n return _isEnumerable(source, key)\n ? _setIn(source, key, updater(source[key]))\n : _merge(enumerables, source, {});\n}\n\n/**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\nvar updateKey = _makePartial3(updateIn);\n\n/**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\nfunction updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source, {});\n }\n}\n\n/**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\nfunction updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n}\n\n/**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\nfunction validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n}\n\n/**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\nvar validateWith = _curry2(validate, true);\n\n/**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\nvar values = _valuesFrom(enumerables);\n\n/**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\nfunction _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n}\n\n/**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\nfunction _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n}\n\n/**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\nfunction padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n}\n\n/**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\nfunction padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n}\n\n/**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\nfunction repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n}\n\n/**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\nvar _search = generic(String.prototype.search);\n\n/**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\nfunction testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n}\n\n/**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\nfunction isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n}\n\n/**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\nfunction isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n}\n\nexport { __, adapter, add, allOf, always, anyOf, append, appendTo, application, apply, applyTo, areSVZ, areSame, aritize, asPartial, binary, case_ as case, checker, clamp, clampWithin, collect, compose, condition, contains, count, countBy, curry, curryRight, curryable, curryableRight, debounce, deduct, difference, divide, divideBy, drop, dropFrom, dropLastWhile, dropWhile, enumerables, every, everyIn, filter, filterWith, find, findIndex, findIndexWhere, findLast, findLastIndex, findLastIndexWhere, findLastWhere, findWhere, flatMap, flatMapWith, flatten, flip, forEach, fromPairs, generate, generic, getArgAt, getAt, getIn, getIndex, getKey, getPath, getPathIn, group, groupBy, gt, gte, has, hasKey, hasKeyValue, hasOwn, hasOwnKey, hasPathValue, head, identity, index, indexBy, init, insert, insertAt, intersection, invoker, invokerOn, is, isFinite_ as isFinite, isGT, isGTE, isIn, isInstanceOf, isInteger, isLT, isLTE, isNil, isNull, isSVZ, isSafeInteger, isType, isUndefined, join, joinWith, keySatisfies, keys, last, list, lt, lte, make, map, mapArgs, mapValues, mapValuesWith, mapWith, merge, mergeOwn, modulo, multiply, multiplyBy, not, ownPairs, ownValues, padLeft, padRight, pairs, partial, partialRight, partition, partitionWith, pathExists, pathExistsIn, pathSatisfies, pick, pickIf, pickKeys, pipe, pluck, pluckKey, pull, pullFrom, randomInt, range, reduce, reduceRight, reduceRightWith, reduceWith, remainder, rename, renameKeys, renameWith, repeat, reverse, rotate, rotateBy, setAt, setIn, setIndex, setKey, setPath, setPathIn, shallowFlatten, skip, skipIf, skipKeys, slice, sliceAt, some, someIn, sort, sortWith, sortedInsert, sorter, sorterDesc, subtract, sum, tail, take, takeFrom, takeLastWhile, takeWhile, tapArgs, tear, tearOwn, testWith, throttle, transpose, type, unary, union, unionBy, uniques, uniquesBy, unless, updateAt, updateIn, updateIndex, updateKey, updatePath, updatePathIn, validate, validateWith, values, when, zip, zipWithIndex };\n"]} \ No newline at end of file diff --git a/dist/lamb.js b/dist/lamb.js index 1a07e45..8356039 100644 --- a/dist/lamb.js +++ b/dist/lamb.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli -* @version 0.58.0-alpha.9 +* @version 0.58.0 * @module lamb * @license MIT */ @@ -1553,8 +1553,8 @@ var findLastIndexWhere = _curry2(findLastIndex, true); /** - * A curried version of {@link module:lamb.findLast|findLast} expecting the array-like object - * to search. + * A curried version of {@link module:lamb.findLast|findLast} that uses the given + * predicate to build a function expecting the array-like object to search. * @example * var isEven = function (n) { return n % 2 === 0; }; * var findEven = _.findLastWhere(isEven); @@ -1577,8 +1577,8 @@ var findLastWhere = _curry2(findLast, true); /** - * A curried version of {@link module:lamb.find|find} expecting the array-like object - * to search. + * A curried version of {@link module:lamb.find|find} that uses the given + * predicate to build a function expecting the array-like object to search. * @example * var isEven = function (n) { return n % 2 === 0; }; * var findEven = _.findWhere(isEven); @@ -4121,7 +4121,7 @@ * to mimic conditional logic or pattern matching, and also to build polymorphic functions. * @example * var isEven = function (n) { return n % 2 === 0; }; - * var filterString = _.compose(_.invoker("join", [""]), _.filter); + * var filterString = _.compose(_.joinWith(""), _.filter); * var filterAdapter = _.adapter([ * _.invoker("filter"), * _.case(_.isType("String"), filterString) diff --git a/dist/lamb.min.js b/dist/lamb.min.js index 6ee7ec1..c65d785 100644 --- a/dist/lamb.min.js +++ b/dist/lamb.min.js @@ -1,7 +1,7 @@ /** * @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming. * @author Andrea Scartabelli -* @version 0.58.0-alpha.9 +* @version 0.58.0 * @module lamb * @license MIT */ diff --git a/dist/lamb.min.js.map b/dist/lamb.min.js.map index 24154e7..006c984 100644 --- a/dist/lamb.min.js.map +++ b/dist/lamb.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["lamb.js"],"names":["global","factory","exports","module","define","amd","self","lamb","this","__","areSVZ","a","b","binary","fn","call","clamp","n","min","max","NaN","partial","args","Array","isArray","apply","arguments","boundArg","lastIdx","newArgs","argsLen","length","i","len","_makePartial3","shouldAritize","clampWithin","identity","value","compose","MAX_ARRAY_LENGTH","MAX_SAFE_INTEGER","_toArrayLength","forEach","arrayLike","iteratee","generic","Function","bind","isNull","isUndefined","isNil","_curry2","isRightCurry","isSVZ","map","result","mapWith","_makeReducer","step","accumulator","initialValue","nCalls","idx","TypeError","reduce","reduceWith","_toInteger","Math","floor","abs","slice","start","end","begin","upTo","resultLen","sliceAt","objectProtoToString","Object","prototype","toString","type","appendTo","concat","append","isIn","contains","_groupWith","makeValue","element","key","count","countBy","filter","predicate","push","not","uniquesBy","seen","uniques","dropFrom","drop","_takeOrDropWhile","isTake","fromLast","idxFrom","idxTo","lastHitIndex","increment","_getLastHitIndex","dropLastWhile","dropWhile","_makeArrayChecker","defaultResult","everyIn","every","filterWith","_findIndex","findIndex","find","findIndexWhere","findLastIndex","findLast","findLastIndexWhere","findLastWhere","findWhere","flatMap","array","el","arr","v","rLen","flatMapWith","_makeArrayFlattener","isDeep","_flatten","output","j","vLen","flatten","_toNaturalIndex","getIndex","index","getAt","group","groupBy","head","indexBy","init","insert","splice","insertAt","join","separator","String","joinWith","last","list","partition","partitionWith","getIn","obj","getKey","pluckKey","pullFrom","values","pull","reduceRight","reduceRightWith","rotate","amount","shift","rotateBy","_setIndex","updater","setAt","aritize","arity","setIndex","shallowFlatten","someIn","some","_compareWith","criteria","criterion","compare","isDescending","_comparer","_sorter","reader","comparer","_makeCriterion","_makeCriteria","sorters","sort","sorter","sorterDesc","sortWith","tail","takeFrom","take","takeLastWhile","takeWhile","transpose","minLen","elementLen","_makeTypeErrorFor","desiredType","toLowerCase","pipe","functions","unionBy","union","updateIndex","zipWithIndex","application","applyTo","_curry","isAutoCurry","_currier","argsHolder","holderLen","newArgsLen","reverse","c","_curry3","_invoker","methodName","boundArgs","target","method","boundArgsLen","finalArgsLen","finalArgs","ofs","_checkPredicates","checkAll","predicates","allOf","anyOf","areSame","gt","gte","is","isGT","isGTE","lt","isLT","lte","isLTE","sum","add","subtract","deduct","divide","divideBy","isInteger","multiply","multiplyBy","_forceToNumber","_isOwnEnumerable","propertyIsEnumerable","_safeEnumerables","_isEnumerable","indexOf","_getPathKey","includeNonEnumerables","_getPathInfo","parts","walkNonEnumerables","isValid","_toPathParts","path","split","getPathIn","_unsafeKeyListFrom","getKeys","enumerables","getPath","has","hasKey","hasOwn","hasOwnProperty","hasOwnKey","keys","make","names","valuesLen","mapValues","source","mapValuesWith","_merge","merge","mergeOwn","_keyToPairIn","_pairsFrom","ownPairs","_valuesFrom","ownValues","pairs","pathExistsIn","pathExists","pick","whitelist","pickIf","pickKeys","rename","keysMap","oldKeys","prop","renameKeys","_setIn","setIn","setKey","_setPathIn","partsLen","targetKey","_isArrayIndex","setPathIn","skip","blacklist","props","skipIf","skipKeys","_tearFrom","tear","tearOwn","updateIn","updateKey","updatePathIn","pathInfo","validate","checkers","errors","_checker","validateWith","_repeat","times","_getPadding","char","ceil","_search","search","adapter","always","asPartial","_asPartial","case","checker","message","keyPaths","pathSeparator","getValues","collect","condition","trueFn","falseFn","curry","curryRight","curryable","curryableRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","difference","other","isNotInOther","flip","fromPairs","pairsList","pair","generate","limit","getArgAt","hasKeyValue","hasPathValue","intersection","lenA","invoker","invokerOn","isFinite","isInstanceOf","constructor","isSafeInteger","isType","typeName","keySatisfies","mapArgs","mapper","modulo","padLeft","padRight","partialRight","pathSatisfies","pluck","randomInt","random","range","remainder","renameWith","repeat","setPath","sortedInsert","_getInsertionIndex","pivot","tapArgs","tappers","tappersLen","testWith","pattern","s","throttle","lastCall","now","Date","unary","unless","updateAt","updatePath","when","zip","defineProperty"],"mappings":";;;;;;;CAOC,SAAUA,EAAQC,GACI,iBAAZC,SAA0C,oBAAXC,OAAyBF,EAAQC,SACrD,mBAAXE,QAAyBA,OAAOC,IAAMD,OAAO,CAAC,WAAYH,GACvCA,GAAzBD,EAASA,GAAUM,MAAqBC,KAAO,IAHpD,CAIEC,KAAM,SAAUN,GAAW,aAYzB,IAAIO,EAAK,GA0DT,SAASC,EAAQC,EAAGC,GAChB,OAAOD,GAAMA,EAAIC,GAAMA,EAAID,IAAMC,EAmBrC,SAASC,EAAQC,GACb,OAAO,SAAUH,EAAGC,GAChB,OAAOE,EAAGC,KAAKP,KAAMG,EAAGC,IA2BhC,SAASI,EAAOC,EAAGC,EAAKC,GAKpB,OAJAF,GAAKA,GACLC,GAAOA,IACPC,GAAOA,GAGIC,IAEAH,EAAIC,EAAMA,EAAMD,EAAIE,EAAMA,EAAMF,EAiC/C,SAASI,EAASP,EAAIQ,GAClB,OAAO,WACH,IAAKC,MAAMC,QAAQF,GACf,OAAOR,EAAGW,MAAMjB,KAAMkB,WAO1B,IAJA,IAIgBC,EAJZC,EAAU,EACVC,EAAU,GACVC,EAAUR,EAAKS,OAEVC,EAAI,EAAaA,EAAIF,EAASE,IACnCL,EAAWL,EAAKU,GAChBH,EAAQG,GAAKL,IAAalB,EAAKiB,UAAUE,KAAaD,EAG1D,IAAK,IAAIM,EAAMP,UAAUK,OAAQH,EAAUK,EAAKL,IAC5CC,EAAQG,KAAON,UAAUE,GAG7B,OAAOd,EAAGW,MAAMjB,KAAMqB,IAe9B,SAASK,EAAepB,EAAIqB,GACxB,OAAO,SAAUxB,EAAGC,GAGhB,OAAOS,EAFCc,GAAsC,IAArBT,UAAUK,OAAelB,EAAOC,GAAMA,EAE7C,CAACL,EAAIE,EAAGC,KAyBlC,IAAIwB,EAAcF,EAAclB,GAgBhC,SAASqB,EAAUC,GACf,OAAOA,EA6BX,SAASC,EAAS5B,EAAGC,GACjB,OAAOc,UAAUK,OAAS,WACtB,OAAOpB,EAAEI,KAAKP,KAAMI,EAAEa,MAAMjB,KAAMkB,aAClCW,EAGR,IAAIG,EAAmB,WACnBC,EAAmB,iBASvB,SAASC,EAAgBJ,GACrB,OAAOtB,EAAMsB,EAAO,EAAGE,KAAsB,EAwBjD,SAASG,EAASC,EAAWC,GACzB,IAAK,IAAIb,EAAI,EAAGC,EAAMS,EAAeE,EAAUb,QAASC,EAAIC,EAAKD,IAC7Da,EAASD,EAAUZ,GAAIA,EAAGY,GAuBlC,IAAIE,EAAUC,SAASC,KAAKA,KAAKD,SAAShC,MAgB1C,SAASkC,EAAQX,GACb,OAAiB,OAAVA,EAiBX,SAASY,EAAaZ,GAClB,YAAiB,IAAVA,EAoBX,SAASa,EAAOb,GACZ,OAAOW,EAAOX,IAAUY,EAAYZ,GAUxC,SAASc,EAAStC,EAAIuC,GAClB,OAAO,SAAU1C,GACb,OAAO,SAAUC,GACb,OAAOyC,EAAevC,EAAGC,KAAKP,KAAMI,EAAGD,GAAKG,EAAGC,KAAKP,KAAMG,EAAGC,KAyCzE,IAAI0C,EAAQF,EAAQ1C,GAoBpB,SAAS6C,EAAKX,EAAWC,GAIrB,IAHA,IAAIZ,EAAMS,EAAeE,EAAUb,QAC/ByB,EAASjC,MAAMU,GAEVD,EAAI,EAAGA,EAAIC,EAAKD,IACrBwB,EAAOxB,GAAKa,EAASD,EAAUZ,GAAIA,EAAGY,GAG1C,OAAOY,EAqBX,IAAIC,EAAUL,EAAQG,GAAK,GAwE3B,SAASG,EAAcC,GACnB,OAAO,SAAUf,EAAWgB,EAAaC,GACrC,IAEIC,EACAN,EAHAvB,EAAMS,EAAeE,EAAUb,QAC/BgC,EAAe,IAATJ,EAAa,EAAI1B,EAAM,EAIjC,GAAyB,IAArBP,UAAUK,OACV+B,EAAS7B,EACTuB,EAASK,MACN,CACH,GAAY,IAAR5B,EACA,MAAM,IAAI+B,UAAU,oDAGxBR,EAASZ,EAAUmB,GACnBA,GAAOJ,EACPG,EAAS7B,EAAM,EAGnB,KAAO6B,IAAUC,GAAOJ,EACpBH,EAASI,EAAYJ,EAAQZ,EAAUmB,GAAMA,EAAKnB,GAGtD,OAAOY,GAsBf,IAAIS,EAASP,EAAa,GAuBtBQ,EAAahC,EAAc+B,GAAQ,GAQvC,SAASE,EAAY7B,GACjB,IAAIrB,GAAKqB,EAET,OAAIrB,GAAMA,EACC,EACAA,EAAI,GAAM,EACVA,EAEAmD,KAAKC,MAAMD,KAAKE,IAAIrD,KAAOA,EAAI,GAAK,EAAI,GA6BvD,SAASsD,EAAO3B,EAAW4B,EAAOC,GAC9B,IAAIxC,EAAMS,EAAeE,EAAUb,QAC/B2C,EAAQP,EAAWK,GACnBG,EAAOR,EAAWM,GAElBC,EAAQ,IACRA,EAAQA,GAASzC,EAAM,EAAIyC,EAAQzC,GAGnC0C,EAAO,EACPA,EAAOA,GAAQ1C,EAAM,EAAI0C,EAAO1C,EACzB0C,EAAO1C,IACd0C,EAAO1C,GAMX,IAHA,IAAI2C,EAAYD,EAAOD,EACnBlB,EAASoB,EAAY,EAAIrD,MAAMqD,GAAa,GAEvC5C,EAAI,EAAGA,EAAI4C,EAAW5C,IAC3BwB,EAAOxB,GAAKY,EAAU8B,EAAQ1C,GAGlC,OAAOwB,EA0BX,IAAIqB,EAAU3C,EAAcqC,GAExBO,EAAsBC,OAAOC,UAAUC,SAuB3C,SAASC,EAAM5C,GACX,OAAOwC,EAAoB/D,KAAKuB,GAAOiC,MAAM,GAAI,GAoBrD,SAASY,EAAUvC,EAAWN,GAC1B,OAAOiC,EAAM3B,EAAW,EAAGA,EAAUb,QAAQqD,OAAO,CAAC9C,IAqBzD,IAAI+C,EAASjC,EAAQ+B,GAAU,GAwB/B,SAASG,EAAM1C,EAAWN,GAGtB,IAFA,IAAIkB,GAAS,EAEJxB,EAAI,EAAGC,EAAMW,EAAUb,OAAQC,EAAIC,EAAKD,IAC7C,GAAItB,EAAO4B,EAAOM,EAAUZ,IAAK,CAC7BwB,GAAS,EACT,MAIR,OAAOA,EAqBX,IAAI+B,EAAWnC,EAAQkC,GAAM,GAQ7B,SAASE,EAAYC,GACjB,OAAO,SAAU7C,EAAWC,GAIxB,IAHA,IAGgB6C,EAASC,EAHrBnC,EAAS,GACTvB,EAAMW,EAAUb,OAEXC,EAAI,EAAiBA,EAAIC,EAAKD,IAGnCwB,EADAmC,EAAM9C,EADN6C,EAAU9C,EAAUZ,GACIA,EAAGY,IACb6C,EAAUjC,EAAOmC,GAAMD,GAGzC,OAAOlC,GA6Bf,IAAIoC,EAAQJ,EAAW,SAAU7E,GAC7B,OAAOA,IAAMA,EAAI,IA4BjBkF,EAAUzC,EAAQwC,GAAO,GAsB7B,SAASE,EAAQlD,EAAWmD,GAIxB,IAHA,IAAI9D,EAAMW,EAAUb,OAChByB,EAAS,GAEJxB,EAAI,EAAGA,EAAIC,EAAKD,IACrB+D,EAAUnD,EAAUZ,GAAIA,EAAGY,IAAcY,EAAOwC,KAAKpD,EAAUZ,IAGnE,OAAOwB,EAkBX,SAASyC,EAAKF,GACV,OAAO,WACH,OAAQA,EAAUtE,MAAMjB,KAAMkB,YAgCtC,SAASwE,EAAWrD,GAChB,OAAO,SAAUD,GAGb,IAFA,IAEmDN,EAF/CkB,EAAS,GAEJxB,EAAI,EAAGC,EAAMW,EAAUb,OAAQoE,EAAO,GAAWnE,EAAIC,EAAKD,IAG1DsD,EAAKa,EAFV7D,EAAQO,EAASD,EAAUZ,GAAIA,EAAGY,MAG9BuD,EAAKH,KAAK1D,GACVkB,EAAOwC,KAAKpD,EAAUZ,KAI9B,OAAOwB,GAuBf,IAAI4C,EAAUF,EAAU7D,GAqDxB,SAASgE,EAAUzD,EAAW3B,GAC1B,OAAOsD,EAAM3B,EAAW3B,EAAG2B,EAAUb,QAwBzC,IAAIuE,EAAOlD,EAAQiD,GAAU,GAuC7B,SAASE,EAAkBC,EAAQC,GAC/B,OAAO,SAAUV,GACb,OAAO,SAAUnD,GACb,IAAI8D,EACAC,EACAC,EAlChB,SAA2BhE,EAAWmD,EAAWU,GAC7C,IAAI1C,EACA8C,EACA5E,EAAMW,EAAUb,OAUpB,IARI0E,GACA1C,EAAM9B,EAAM,EACZ4E,GAAa,IAEb9C,EAAM,EACN8C,EAAY,GAGT9C,GAAO,GAAKA,EAAM9B,GAAO8D,EAAUnD,EAAUmB,GAAMA,EAAKnB,IAC3DmB,GAAO8C,EAGX,OAAO9C,EAiBoB+C,CAAiBlE,EAAWmD,EAAWU,GAgB1D,OAdID,GAAUC,GACVC,EAAUE,EAAe,EACzBD,EAAQ/D,EAAUb,QACXyE,GACPE,EAAU,EACVC,EAAQC,IACAJ,GAAUC,GAClBC,EAAU,EACVC,EAAQC,EAAe,IAEvBF,EAAUE,EACVD,EAAQ/D,EAAUb,QAGfwC,EAAM3B,EAAW8D,EAASC,KA0B7C,IAAII,EAAgBR,GAAiB,GAAO,GAuBxCS,EAAYT,GAAiB,GAAO,GASxC,SAASU,EAAmBC,GACxB,OAAO,SAAUtE,EAAWmD,GACxB,IAAK,IAAI/D,EAAI,EAAGC,EAAMW,EAAUb,OAAQC,EAAIC,EAAKD,IAC7C,GAAIkF,IAAkBnB,EAAUnD,EAAUZ,GAAIA,EAAGY,GAC7C,OAAQsE,EAIhB,OAAOA,GA2Cf,IAAIC,EAAUF,GAAkB,GAuB5BG,EAAQhE,EAAQ+D,GAAS,GAsBzBE,EAAajE,EAAQ0C,GAAQ,GAWjC,SAASwB,EAAY1E,EAAWmD,EAAWU,GACvC,IAAIjC,EACAqC,EACA5E,EAAMW,EAAUb,OAChByB,GAAU,EAEViD,GACAjC,EAAQvC,EAAM,EACd4E,GAAa,IAEbrC,EAAQ,EACRqC,EAAY,GAGhB,IAAK,IAAI7E,EAAIwC,EAAOxC,EAAIC,GAAOD,GAAK,EAAGA,GAAK6E,EACxC,GAAId,EAAUnD,EAAUZ,GAAIA,EAAGY,GAAY,CACvCY,EAASxB,EACT,MAIR,OAAOwB,EA6BX,SAAS+D,EAAW3E,EAAWmD,GAC3B,OAAOuB,EAAW1E,EAAWmD,GAAW,GA6B5C,SAASyB,EAAM5E,EAAWmD,GACtB,IAAIhC,EAAMwD,EAAU3E,EAAWmD,GAE/B,OAAgB,IAAThC,OAAa,EAASnB,EAAUmB,GAyB3C,IAAI0D,EAAiBrE,EAAQmE,GAAW,GA2BxC,SAASG,GAAe9E,EAAWmD,GAC/B,OAAOuB,EAAW1E,EAAWmD,GAAW,GA6B5C,SAAS4B,GAAU/E,EAAWmD,GAC1B,IAAIhC,EAAM2D,GAAc9E,EAAWmD,GAEnC,OAAgB,IAAThC,OAAa,EAASnB,EAAUmB,GAwB3C,IAAI6D,GAAqBxE,EAAQsE,IAAe,GAwB5CG,GAAgBzE,EAAQuE,IAAU,GAwBlCG,GAAY1E,EAAQoE,GAAM,GAqB9B,SAASO,GAASC,EAAOnF,GACrB,OAAOoB,EAAO+D,EAAO,SAAUxE,EAAQyE,EAAIlE,EAAKmE,GAC5C,IAAIC,EAAItF,EAASoF,EAAIlE,EAAKmE,GAErB3G,MAAMC,QAAQ2G,KACfA,EAAI,CAACA,IAGT,IAAK,IAAInG,EAAI,EAAGC,EAAMkG,EAAEpG,OAAQqG,EAAO5E,EAAOzB,OAAQC,EAAIC,EAAKD,IAC3DwB,EAAO4E,EAAOpG,GAAKmG,EAAEnG,GAGzB,OAAOwB,GACR,IAqBP,IAAI6E,GAAcjF,EAAQ2E,IAAS,GAyCnC,IAAIO,GAAsBlF,EAAQ,SAAUmF,EAAQP,GAChD,OAAOzG,MAAMC,QAAQwG,GA/BzB,SAASQ,EAAUR,EAAOO,EAAQE,EAAQ1E,GACtC,IAAK,IAA+BzB,EAAOoG,EAAGC,EAArC3G,EAAI,EAAGC,EAAM+F,EAAMjG,OAAwBC,EAAIC,EAAKD,IAGzD,GAFAM,EAAQ0F,EAAMhG,GAETT,MAAMC,QAAQc,GAEZ,GAAIiG,EACPC,EAASlG,GAAO,EAAMmG,EAAQ1E,GAC9BA,EAAM0E,EAAO1G,YAKb,IAHA4G,EAAOrG,EAAMP,OACb0G,EAAO1G,QAAU4G,EAEZD,EAAI,EAAGA,EAAIC,EAAMD,IAClBD,EAAO1E,KAASzB,EAAMoG,QAT1BD,EAAO1E,KAASzB,EAcxB,OAAOmG,EAYuBD,CAASR,EAAOO,EAAQ,GAAI,GAAKhE,EAAMyD,EAAO,EAAGA,EAAMjG,UAmBrF6G,GAAUN,IAAoB,GAWlC,SAASO,GAAiB9E,EAAK9B,GAG3B,OAFA8B,EAAMI,EAAWJ,MAEF9B,GAAO8B,EAAM9B,EAAM8B,EAAM,EAAIA,EAAM9B,EAAM8B,EAAM3C,IA0BlE,SAAS0H,GAAUlG,EAAWmG,GAC1B,IAAIhF,EAAM8E,GAAgBE,EAAOrG,EAAeE,EAAUb,SAE1D,OAAOgC,GAAQA,EAAMnB,EAAUmB,QAAO,EA2B1C,IAAIiF,GAAQ5F,EAAQ0F,IAAU,GA4D1BG,GAAQzD,EAAW,SAAU7E,EAAGC,GAChC,OAAKD,GAILA,EAAEA,EAAEoB,QAAUnB,EAEPD,GALI,CAACC,KA8CZsI,GAAU9F,EAAQ6F,IAAO,GAmBzBE,GAAOH,GAAM,GAqDbD,GAAQvD,EAAW,SAAU7E,EAAGC,GAChC,OAAOA,IAiCPwI,GAAUhG,EAAQ2F,IAAO,GAkBzBM,GAAOhI,EAAQkD,EAAO,CAAC9D,EAAI,GAAI,IA4BnC,SAAS6I,GAAQ1G,EAAWmG,EAAOrD,GAC/B,IAAIlC,EAASe,EAAM3B,EAAW,EAAGA,EAAUb,QAI3C,OAFAyB,EAAO+F,OAAOR,EAAO,EAAGrD,GAEjBlC,EAyBX,IAAIgG,GAAWtH,EAAcoH,IAmE7B,SAASG,GAAM7G,EAAW8G,GACtB,OAAOnG,EAAIX,EAAW+G,QAAQF,KAAKE,OAAOD,IAsB9C,IAAIE,GAAWxG,EAAQqG,IAAM,GAmBzBI,GAAOb,IAAO,GAuClB,IA3B2BjF,GA2BvB+F,IA3BuB/F,GA2BC,EA1BjB,WAKH,IAJA,IACI9B,GADUP,UAAUK,QAAUgC,IACdA,GAChBP,EAASjC,MAAMU,GAEVD,EAAI,EAAGA,EAAIC,EAAKD,IACrBwB,EAAOxB,GAAKN,UAAUM,EAAI+B,IAG9B,OAAOP,IAoCf,SAASuG,GAAWnH,EAAWmD,GAI3B,IAHA,IAGgBkC,EAHZzE,EAAS,CAAC,GAAI,IACdvB,EAAMW,EAAUb,OAEXC,EAAI,EAAOA,EAAIC,EAAKD,IAEzBwB,EAAOuC,EADPkC,EAAKrF,EAAUZ,GACMA,EAAGY,GAAa,EAAI,GAAGoD,KAAKiC,GAGrD,OAAOzE,EAiCX,IAAIwG,GAAgB5G,EAAQ2G,IAAW,GAmBvC,SAASE,GAAOC,EAAKvE,GACjB,OAAOuE,EAAIvE,GAwBf,IAAIwE,GAAS/G,EAAQ6G,IAAO,GAwD5B,IAAIG,GAAW7H,EAAQkB,EAAS0G,IA2BhC,SAASE,GAAUzH,EAAW0H,GAC1B,OAAOA,EAASxE,EAAOlD,EAAW,SAAU8C,GACxC,OAAQJ,EAAKgF,EAAQ5E,KACpBnB,EAAM3B,EAAW,EAAGA,EAAUb,QA2BvC,IAAIwI,GAAOnH,EAAQiH,IAAU,GAiBzBG,GAAc9G,GAAc,GAuB5B+G,GAAkBvI,EAAcsI,IAAa,GA8CjD,SAASE,GAAQ9H,EAAW+H,GACxB,IAAI1I,EAAMW,EAAUb,OAChB6I,EAAQD,EAAS1I,EAErB,OAAOsC,EAAM3B,GAAYgI,EAAO3I,GAAKmD,OAAOb,EAAM3B,EAAW,GAAIgI,IAoBrE,IAAIC,GAAWzH,EAAQsH,IAAQ,GAa/B,SAASI,GAAWlI,EAAWmB,EAAKzB,EAAOyI,GACvC,IAAIvH,EAASe,EAAM3B,EAAW,EAAGA,EAAUb,QACvCd,EAAI4H,GAAgB9E,EAAKP,EAAOzB,QAMpC,OAJId,GAAMA,IACNuC,EAAOvC,GAA0B,IAArBS,UAAUK,OAAegJ,EAAQnI,EAAU3B,IAAMqB,GAG1DkB,EA8BX,IAAIwH,GAAQ9I,EAAc4I,IAqB1B,SAASG,GAASnK,EAAIoK,GAClB,OAAO,WAIH,IAHA,IAAIjK,EAAIkD,EAAW+G,GACf5J,EAAOwI,GAAKrI,MAAM,KAAMC,WAAW6C,MAAM,EAAGtD,GAEvCe,EAAIV,EAAKS,OAAQC,EAAIf,EAAGe,IAC7BV,EAAKU,QAAK,EAGd,OAAOlB,EAAGW,MAAMjB,KAAMc,IA2B9B,IAAI6J,GAAWF,GAAQH,GAAW,GAkB9BM,GAAiB9C,IAAoB,GAsCrC+C,GAASpE,GAAkB,GAuB3BqE,GAAOlI,EAAQiI,IAAQ,GAS3B,SAASE,GAAcC,GACnB,OAAO,SAAU7K,EAAGC,GAKhB,IAJA,IAAIqB,EAAMuJ,EAASzJ,OACf0J,EAAYD,EAAS,GACrBhI,EAASiI,EAAUC,QAAQ/K,EAAE2B,MAAO1B,EAAE0B,OAEjCN,EAAI,EAAc,IAAXwB,GAAgBxB,EAAIC,EAAKD,IAErCwB,GADAiI,EAAYD,EAASxJ,IACF0J,QAAQ/K,EAAE2B,MAAO1B,EAAE0B,OAO1C,OAJe,IAAXkB,IACAA,EAAS7C,EAAEoI,MAAQnI,EAAEmI,OAGlB0C,EAAUE,cAAgBnI,EAASA,GAclD,SAASoI,GAAWjL,EAAGC,GACnB,IAAI4C,EAAS,EAYb,cAVW7C,UAAaC,IACpBD,EAAIgJ,OAAOhJ,GACXC,EAAI+I,OAAO/I,IAGVF,EAAOC,EAAGC,KAEX4C,EAAS7C,EAAIC,GAAKD,GAAMA,EAAI,GAAK,GAG9B6C,EAYX,SAASqI,GAASC,EAAQH,EAAcI,GASpC,MARsB,mBAAXD,GAAyBA,IAAWzJ,IAC3CyJ,EAAS,MAGW,mBAAbC,IACPA,EAAWH,IAGR,CACHD,cAA+B,IAAjBA,EACdD,QAAS,SAAU/K,EAAGC,GAMlB,OALIkL,IACAnL,EAAImL,EAAOnL,GACXC,EAAIkL,EAAOlL,IAGRmL,EAASpL,EAAGC,KAW/B,SAASoL,GAAgBP,GACrB,OAAOA,GAA0C,mBAAtBA,EAAUC,QAAyBD,EAAYI,GAAQJ,GAUtF,SAASQ,GAAeC,GACpB,OAAOA,GAAWA,EAAQnK,OAASwB,EAAI2I,EAASF,IAAkB,CAACH,MAgEvE,SAASM,GAAMvJ,EAAWsJ,GAKtB,IAJA,IAAIV,EAAWS,GAAcC,GACzBjK,EAAMS,EAAeE,EAAUb,QAC/ByB,EAASjC,MAAMU,GAEVD,EAAI,EAAGA,EAAIC,EAAKD,IACrBwB,EAAOxB,GAAK,CAAEM,MAAOM,EAAUZ,GAAI+G,MAAO/G,GAK9C,IAFAwB,EAAO2I,KAAKZ,GAAaC,IAEpBxJ,EAAI,EAAGA,EAAIC,EAAKD,IACjBwB,EAAOxB,GAAKwB,EAAOxB,GAAGM,MAG1B,OAAOkB,EAmHX,IAAI4I,GAAS/K,EAAQwK,GAAS,CAACpL,GAAI,EAAOA,IAoBtC4L,GAAahL,EAAQwK,GAAS,CAACpL,GAAI,EAAMA,IA0BzC6L,GAAWlJ,EAAQ+I,IAAM,GAkBzBI,GAAOjG,EAAK,GAwBhB,SAASkG,GAAU5J,EAAW3B,GAC1B,OAAOsD,EAAM3B,EAAW,EAAG3B,GAwB/B,IAAIwL,GAAOrJ,EAAQoJ,IAAU,GAuBzBE,GAAgBnG,GAAiB,GAAM,GAuBvCoG,GAAYpG,GAAiB,GAAM,GA8BvC,SAASqG,GAAWhK,GAChB,IAAIiK,EAASrK,EACTP,EAAMS,EAAeE,EAAUb,QAEnC,GAAY,IAARE,EACA,MAAO,GAGX,IAAK,IAAW6K,EAAPpE,EAAI,EAAeA,EAAIzG,EAAKyG,KACjCoE,EAAapK,EAAeE,EAAU8F,GAAG3G,SAExB8K,IACbA,EAASC,GAMjB,IAFA,IAEgB7E,EAFZzE,EAASjC,MAAMsL,GAEV7K,EAAI,EAAOA,EAAI6K,EAAQ7K,IAG5B,IAFAiG,EAAKzE,EAAOxB,GAAKT,MAAMU,GAElByG,EAAI,EAAGA,EAAIzG,EAAKyG,IACjBT,EAAGS,GAAK9F,EAAU8F,GAAG1G,GAI7B,OAAOwB,EAWX,SAASuJ,GAAmBzK,EAAO0K,GAC/B,OAAO,IAAIhJ,UAAU,kBAAoBkB,EAAK5C,GAAO2K,cAAgB,OAASD,GAoBlF,SAASE,GAAMC,GACX,IAAK5L,MAAMC,QAAQ2L,GACf,MAAMJ,GAAkBI,EAAW,SAGvC,IAAIlL,EAAMkL,EAAUpL,OAEpB,OAAOE,EAAM,WAGT,IAFA,IAAIuB,EAAS2J,EAAU,GAAG1L,MAAMjB,KAAMkB,WAE7BM,EAAI,EAAGA,EAAIC,EAAKD,IACrBwB,EAAS2J,EAAUnL,GAAGjB,KAAKP,KAAMgD,GAGrC,OAAOA,GACPnB,EAyBR,SAAS+K,GAASvK,GACd,OAAOqK,GAAK,CAACrM,EAAOiJ,IAAOzB,GAAY/B,EAAK,IAAKJ,EAAUrD,KA0B/D,IAAIwK,GAAQD,GAAQ/K,GAsDpB,IAAIiL,GAAcjM,EAAQyJ,GAAW,CAACrK,EAAIA,EAAI,KAAMA,IAwCpD,IAAI8M,GAAe9J,EAAQ5C,EAAOiJ,KAelC,SAAS0D,GAAa1M,EAAIQ,GACtB,OAAOR,EAAGW,MAAMjB,KAAMuE,OAAOzD,IAmBjC,IAAIG,GAAQ2B,EAAQoK,IAoBhBC,GAAUrK,EAAQoK,IAAa,GAiMnC,SAASE,GAAQ5M,EAAIoK,EAAO7H,EAAcsK,GAKtC,OAJIzC,IAAU,IAAMA,IAChBA,EAAQpK,EAAGiB,QAGX4L,GAAezC,EAAQ,GAAKA,EAAQ,EA1D5C,SAAS0C,EAAU9M,EAAIoK,EAAO7H,EAAcsK,EAAaE,GACrD,OAAO,WAMH,IALA,IAAIC,EAAYD,EAAW9L,OACvBD,EAAUJ,UAAUK,OACpBgM,EAAaD,GAAahM,EAAU,GAAK6L,EAAc7L,EAAU,GACjED,EAAUN,MAAMwM,GAEX/L,EAAI,EAAGA,EAAI8L,EAAW9L,IAC3BH,EAAQG,GAAK6L,EAAW7L,GAG5B,KAAOA,EAAI+L,EAAY/L,IACnBH,EAAQG,GAAKN,UAAUM,EAAI8L,GAG/B,OAAIC,GAAc7C,EACPpK,EAAGW,MAAMjB,KAAM6C,EAAexB,EAAQmM,UAAYnM,GAElD+L,EAAS9M,EAAIoK,EAAO7H,EAAcsK,EAAa9L,IAyCnD+L,CAAS9M,EAAIoK,EAAO7H,EAAcsK,EAAa,IACrC,IAAVzC,EACA9H,EAAQtC,EAAIuC,GACF,IAAV6H,EAhCf,SAAkBpK,EAAIuC,GAClB,OAAO,SAAU1C,GACb,OAAO,SAAUC,GACb,OAAO,SAAUqN,GACb,OAAO5K,EAAevC,EAAGC,KAAKP,KAAMyN,EAAGrN,EAAGD,GAAKG,EAAGC,KAAKP,KAAMG,EAAGC,EAAGqN,MA6BpEC,CAAQpN,EAAIuC,GAEZvC,EAoNf,SAASqN,GAAUC,EAAYC,EAAWC,GACtC,IAAIC,EAASD,EAAOF,GAEpB,GAAsB,mBAAXG,EAAX,CAQA,IAJA,IAAIC,EAAeH,EAAY3L,EAAe2L,EAAUtM,QAAU,EAC9D0M,EAAeD,EAAe9M,UAAUK,OAAS,EACjD2M,EAAYnN,MAAMkN,GAEbzM,EAAI,EAAGA,EAAIwM,EAAcxM,IAC9B0M,EAAU1M,GAAKqM,EAAUrM,GAG7B,IAAK,IAAI2M,EAAM,EAAI3M,EAAGA,EAAIyM,EAAczM,IACpC0M,EAAU1M,GAAKN,UAAUM,EAAI2M,GAGjC,OAAOJ,EAAO9M,MAAM6M,EAAQI,IAkPhC,SAASE,GAAkBC,GACvB,OAAO,SAAUC,GACb,IAAKvN,MAAMC,QAAQsN,GACf,MAAM/B,GAAkB+B,EAAY,SAGxC,OAAO,WACH,IAAK,IAAoCtL,EAAhCxB,EAAI,EAAGC,EAAM6M,EAAW/M,OAAgBC,EAAIC,EAAKD,IAAK,CAG3D,GAFAwB,EAASsL,EAAW9M,GAAGP,MAAMjB,KAAMkB,WAE/BmN,IAAarL,EACb,OAAO,EACJ,IAAKqL,GAAYrL,EACpB,OAAO,EAIf,OAAOqL,IAyBnB,IAAIE,GAAQH,IAAiB,GA2BzBI,GAAQJ,IAAiB,GA+B7B,SAASK,GAAStO,EAAGC,GACjB,OAAa,IAAND,GAAiB,IAANC,EAAU,EAAID,GAAM,EAAIC,EAAIF,EAAOC,EAAGC,GA6F5D,SAASsO,GAAIvO,EAAGC,GACZ,OAAOD,EAAIC,EAyBf,SAASuO,GAAKxO,EAAGC,GACb,OAAOD,GAAKC,EAuChB,IAAIwO,GAAKhM,EAAQ6L,IAwBbI,GAAOjM,EAAQ8L,IAAI,GAyBnBI,GAAQlM,EAAQ+L,IAAK,GA8BzB,SAASI,GAAI5O,EAAGC,GACZ,OAAOD,EAAIC,EAyBf,IAAI4O,GAAOpM,EAAQmM,IAAI,GAwBvB,SAASE,GAAK9O,EAAGC,GACb,OAAOD,GAAKC,EA0BhB,IAAI8O,GAAQtM,EAAQqM,IAAK,GA6EzB,SAASE,GAAKhP,EAAGC,GACb,OAAOD,EAAIC,EAmBf,IAAIgP,GAAMxM,EAAQuM,IAAK,GAevB,SAASE,GAAUlP,EAAGC,GAClB,OAAOD,EAAIC,EAoBf,IAAIkP,GAAS1M,EAAQyM,IAAU,GAe/B,SAASE,GAAQpP,EAAGC,GAChB,OAAOD,EAAIC,EAoBf,IAAIoP,GAAW5M,EAAQ2M,IAAQ,GA0E/B,SAASE,GAAW3N,GAChB,MAAuB,WAAhB4C,EAAK5C,IAAuBA,EAAQ,GAAM,EAwErD,SAAS4N,GAAUvP,EAAGC,GAClB,OAAOD,EAAIC,EAkBf,IAAIuP,GAAa/M,EAAQ8M,IAAU,GA6BnC,SAASE,GAAgB9N,GACrB,IAAIrB,GAAKqB,EAET,OAAOrB,GAAMA,EAAIA,EAAI,EA+EzB,IAAIoP,GAAmBvN,EAAQiC,OAAOC,UAAUsL,sBAShD,SAASC,GAAkBrG,GACvB,IAAI1G,EAAS,GAEb,IAAK,IAAImC,KAAOuE,EACZ1G,EAAOwC,KAAKL,GAGhB,OAAOnC,EAUX,SAASgN,GAAetG,EAAKvE,GACzB,OAAOA,KAAOZ,OAAOmF,KAASmG,GAAiBnG,EAAKvE,KAAS4K,GAAiBrG,GAAKuG,QAAQ9K,IAW/F,SAAS+K,GAAapC,EAAQ3I,EAAKgL,GAC/B,GAAIA,GAAyBhL,KAAOZ,OAAOuJ,IAAWkC,GAAclC,EAAQ3I,GACxE,OAAOA,EAGX,IAAI1E,GAAK0E,EACL1D,EAAMqM,GAAUA,EAAOvM,OAE3B,OAAOd,IAAMgB,GAAOhB,EAAIgB,EAAMhB,EAAI,EAAIA,EAAIgB,EAAMhB,OAAI,EAWxD,SAAS2P,GAAc1G,EAAK2G,EAAOC,GAC/B,GAAI3N,EAAM+G,GACN,MAAM6C,GAAkB7C,EAAK,UAQjC,IALA,IAGIvE,EAHA2I,EAASpE,EACTlI,GAAK,EACLC,EAAM4O,EAAM9O,SAGPC,EAAIC,IAGLiB,EAFJyC,EAAM+K,GAAYpC,EAAQuC,EAAM7O,GAAI8O,KAMpCxC,EAASA,EAAO3I,GAGpB,OAAO3D,IAAMC,EAAM,CAAE8O,SAAS,EAAMzC,OAAQA,GAAW,CAAEyC,SAAS,EAAOzC,YAAQ,GAWrF,SAAS0C,GAAcC,EAAMvH,GACzB,OAAOC,OAAOsH,GAAMC,MAAMxH,GAAa,KAsD3C,SAASyH,GAAWjH,EAAK+G,EAAMvH,GAC3B,OAAOkH,GAAa1G,EAAK8G,GAAaC,EAAMvH,IAAY,GAAM4E,OA2DlE,IAAI8C,GAAqBhO,EAAQ,SAAUiO,EAASnH,GAChD,GAAI/G,EAAM+G,GACN,MAAM6C,GAAkB7C,EAAK,UAGjC,OAAOmH,EAAQnH,KAuBfoH,GAAcF,GAAmBb,IAyDrC,IAAIgB,GAAUrP,EAAciP,IA0B5B,SAASK,GAAKtH,EAAKvE,GAKf,MAJmB,iBAARuE,GAAqBhH,EAAYgH,KACxCA,EAAMnF,OAAOmF,IAGVvE,KAAOuE,EAwBlB,IAAIuH,GAASrO,EAAQoO,IAAK,GA2BtBE,GAAS5O,EAAQiC,OAAOC,UAAU2M,gBAuBlCC,GAAYxO,EAAQsO,IAAQ,GA4EhC,IA2BIG,GAAOT,GA3BK7O,EAAQwC,OAAO8M,KAAM9M,SA4ErC,SAAS+M,GAAMC,EAAOzH,GAIlB,IAHA,IAAI9G,EAAS,GACTwO,EAAY1H,EAAOvI,OAEdC,EAAI,EAAGC,EAAM8P,EAAMhQ,OAAQC,EAAIC,EAAKD,IACzCwB,EAAOuO,EAAM/P,IAAMA,EAAIgQ,EAAY1H,EAAOtI,QAAK,EAGnD,OAAOwB,EAsBX,SAASyO,GAAWC,EAAQpR,GACxB,GAAIqC,EAAM+O,GACN,MAAMnF,GAAkBmF,EAAQ,UAGpC,IAAI1O,EAAS,GAEb,IAAK,IAAImC,KAAOuM,EACZ1O,EAAOmC,GAAO7E,EAAGoR,EAAOvM,GAAMA,EAAKuM,GAGvC,OAAO1O,EAyBX,IAAI2O,GAAgB/O,EAAQ6O,IAAW,GAUvC,SAASG,GAAQf,EAAS1Q,EAAGC,GACzB,OAAOqD,EAAO,CAACtD,EAAGC,GAAI,SAAU4C,EAAQ0O,GAKpC,OAJAvP,EAAQ0O,EAAQa,GAAS,SAAUvM,GAC/BnC,EAAOmC,GAAOuM,EAAOvM,KAGlBnC,GACR,IA0BP,IAAI6O,GAAQhR,EAAQ+Q,GAAQ,CAACd,KAiCzBgB,GAAWjR,EAAQ+Q,GAAQ,CAACP,KAU5BU,GAAenP,EAAQ,SAAU8G,EAAKvE,GACtC,MAAO,CAACA,EAAKuE,EAAIvE,MAWjB6M,GAAapP,EAAQ,SAAUiO,EAASnH,GACxC,OAAO3G,EAAI8N,EAAQnH,GAAMqI,GAAarI,MAyBtCuI,GAAWD,GAAWX,IAUtBa,GAActP,EAAQ,SAAUiO,EAASnH,GACzC,OAAO3G,EAAI8N,EAAQnH,GAAM,SAAUvE,GAC/B,OAAOuE,EAAIvE,OAwBfgN,GAAYD,GAAYb,IAkBxBe,GAAQJ,GAAWlB,IA8BvB,SAASuB,GAAc3I,EAAK+G,EAAMvH,GAC9B,OAAOkH,GAAa1G,EAAK8G,GAAaC,EAAMvH,IAAY,GAAMqH,QAoClE,IAAI+B,GAAa5Q,EAAc2Q,IAyD/B,SAASE,GAAMb,EAAQc,GAGnB,IAFA,IAEwCrN,EAFpCnC,EAAS,GAEJxB,EAAI,EAAGC,EAAM+Q,EAAUjR,OAAaC,EAAIC,EAAKD,IAG9CwP,GAAIU,EAFRvM,EAAMqN,EAAUhR,MAGZwB,EAAOmC,GAAOuM,EAAOvM,IAI7B,OAAOnC,EAsBX,SAASyP,GAAQlN,GACb,OAAO,SAAUmM,GACb,GAAI/O,EAAM+O,GACN,MAAMnF,GAAkBmF,EAAQ,UAGpC,IAAI1O,EAAS,GAEb,IAAK,IAAImC,KAAOuM,EACRnM,EAAUmM,EAAOvM,GAAMA,EAAKuM,KAC5B1O,EAAOmC,GAAOuM,EAAOvM,IAI7B,OAAOnC,GAyCf,IAAI0P,GAAW9P,EAAQ2P,IAAM,GAwB7B,SAASI,GAAQjB,EAAQkB,GACrBA,EAAUrO,OAAOqO,GACjB,IAAI5P,EAAS,GACT6P,EAAU/B,GAAYY,GAE1B,IAAK,IAAIoB,KAAQF,GACRC,EAAQ5C,QAAQ6C,KACjB9P,EAAO4P,EAAQE,IAASpB,EAAOoB,IAIvC,IAAK,IAAiC3N,EAA7B3D,EAAI,EAAGC,EAAMoR,EAAQtR,OAAaC,EAAIC,EAAKD,KAChD2D,EAAM0N,EAAQrR,MAEDoR,GAAWzN,KAAOnC,IAC3BA,EAAOmC,GAAOuM,EAAOvM,IAI7B,OAAOnC,EAgCX,IAAI+P,GAAanQ,EAAQ+P,IAAQ,GAsCjC,SAASK,GAAQtB,EAAQvM,EAAKrD,GAC1B,IAAIkB,EAAS,GAEb,IAAK,IAAI8P,KAAQpB,EACb1O,EAAO8P,GAAQpB,EAAOoB,GAK1B,OAFA9P,EAAOmC,GAAOrD,EAEPkB,EAgCX,SAASiQ,GAAOvB,EAAQvM,EAAKrD,GACzB,GAAIa,EAAM+O,GACN,MAAMnF,GAAkBmF,EAAQ,UAGpC,OAAOsB,GAAOtB,EAAQvM,EAAKrD,GA2B/B,IAAIoR,GAASxR,EAAcuR,IAyB3B,SAASE,GAAYzJ,EAAK2G,EAAOvO,GAC7B,IAEI6F,EAFAxC,EAAMkL,EAAM,GACZ+C,EAAW/C,EAAM9O,OAGrB,GAAiB,IAAb6R,EACAzL,EAAI7F,MACD,CACH,IAAIuR,EAAYnD,GAAYxG,EAAKvE,GAAK,GAEtCwC,EAAIwL,GACAzQ,EAAY2Q,GAAaA,EAAY3J,EAAI2J,GACzCtP,EAAMsM,EAAO,EAAG+C,GAChBtR,GAIR,OAhCJ,SAAwBgM,EAAQ3I,GAC5B,IAAI1E,GAAK0E,EAET,OAAOpE,MAAMC,QAAQ8M,IAAWrN,EAAI,GAAM,KAAOA,EAAI,GAAKuP,GAAclC,EAAQ3I,IA6BzEmO,CAAc5J,EAAKvE,GAAOmF,GAAUZ,EAAKvE,EAAKwC,GAAKqL,GAAOtJ,EAAKvE,EAAKwC,GAwD/E,SAAS4L,GAAW7B,EAAQjB,EAAM3O,EAAOoH,GACrC,GAAIvG,EAAM+O,GACN,MAAMnF,GAAkBmF,EAAQ,UAGpC,OAAOyB,GAAWzB,EAAQlB,GAAaC,EAAMvH,GAAYpH,GA+C7D,SAAS0R,GAAM9B,EAAQ+B,GACnB,GAAI9Q,EAAM+O,GACN,MAAMnF,GAAkBmF,EAAQ,UAGpC,IAAI1O,EAAS,GACT0Q,EAAQpC,GAAKmC,EAAW,IAE5B,IAAK,IAAItO,KAAOuM,EACNvM,KAAOuO,IACT1Q,EAAOmC,GAAOuM,EAAOvM,IAI7B,OAAOnC,EAuBX,IAAI2Q,GAAS5R,EAAQ0Q,GAAQhN,GAuCzBmO,GAAWhR,EAAQ4Q,IAAM,GAYzBK,GAAYjR,EAAQ,SAAUiO,EAASnH,GACvC,OAAOjG,EAAOoN,EAAQnH,GAAM,SAAU1G,EAAQmC,GAI1C,OAHAnC,EAAO,GAAGwC,KAAKL,GACfnC,EAAO,GAAGwC,KAAKkE,EAAIvE,IAEZnC,GACR,CAAC,GAAI,OAoBR8Q,GAAOD,GAAU/C,IAuBjBiD,GAAUF,GAAUxC,IA8BxB,SAAS2C,GAAUtC,EAAQvM,EAAKoF,GAC5B,OAAOyF,GAAc0B,EAAQvM,GACvB6N,GAAOtB,EAAQvM,EAAKoF,EAAQmH,EAAOvM,KACnCyM,GAAOd,GAAaY,EAAQ,IAyBtC,IAAIuC,GAAYvS,EAAcsS,IAgD9B,SAASE,GAAcxC,EAAQjB,EAAMlG,EAASrB,GAC1C,IAAImH,EAAQG,GAAaC,EAAMvH,GAC3BiL,EAAW/D,GAAasB,EAAQrB,GAAO,GAE3C,OAAI8D,EAAS5D,QACF4C,GAAWzB,EAAQrB,EAAO9F,EAAQ4J,EAASrG,SAE3C/M,MAAMC,QAAQ0Q,GAAU3N,EAAM2N,EAAQ,EAAGA,EAAOnQ,QAAUqQ,GAAOd,GAAaY,EAAQ,IAgErG,SAAS0C,GAAU1K,EAAK2K,GACpB,OAAO5Q,EAAO4Q,EAAU,SAAUC,EAAQC,GACtC,IAAIvR,EAASuR,EAAS7K,GAItB,OAFA1G,EAAOzB,QAAU+S,EAAO9O,KAAKxC,GAEtBsR,GACR,IAkCP,IAAIE,GAAe5R,EAAQwR,IAAU,GAkBjCtK,GAASoI,GAAYpB,IASzB,SAAS2D,GAAS/C,EAAQgD,GAGtB,IAFA,IAAI1R,EAAS,GAEJxB,EAAI,EAAGA,EAAIkT,EAAOlT,IACvBwB,GAAU0O,EAGd,OAAO1O,EAWX,SAAS2R,GAAajD,EAAQkD,EAAMnT,GAKhC,OAJKkB,EAAM+O,IAA4B,WAAjBhN,EAAKgN,KACvBA,EAASvI,OAAOuI,IAGb+C,GAAQtL,OAAOyL,GAAM,IAAM,GAAIhR,KAAKiR,KAAKpT,EAAMiQ,EAAOnQ,SAqFjE,IAAIuT,GAAUxS,EAAQ6G,OAAO3E,UAAUuQ,QA8EvCrV,EAAQO,GAAKA,EACbP,EAAQsV,QA7uFR,SAAkBrI,GACd,IAAK5L,MAAMC,QAAQ2L,GACf,MAAMJ,GAAkBI,EAAW,SAGvC,OAAO,WAIH,IAHA,IACI3J,EADAvB,EAAMkL,EAAUpL,OAGXC,EAAI,EAAGA,EAAIC,GAGXiB,EAFLM,EAAS2J,EAAUnL,GAAGP,MAAMjB,KAAMkB,YADbM,KAQzB,OAAOwB,IA6tFftD,EAAQ0P,IAAMA,GACd1P,EAAQ6O,MAAQA,GAChB7O,EAAQuV,OAnvNR,SAAiBnT,GACb,OAAO,WACH,OAAOA,IAkvNfpC,EAAQ8O,MAAQA,GAChB9O,EAAQmF,OAASA,EACjBnF,EAAQiF,SAAWA,EACnBjF,EAAQsN,YAAcA,GACtBtN,EAAQuB,MAAQA,GAChBvB,EAAQuN,QAAUA,GAClBvN,EAAQQ,OAASA,EACjBR,EAAQ+O,QAAUA,GAClB/O,EAAQ+K,QAAUA,GAClB/K,EAAQwV,UA3yGR,SAAoB5U,GAChB,OA5EJ,SAAS6U,EAAY7U,EAAI+M,GACrB,OAAO,WAKH,IAJA,IAIyClM,EAJrCG,EAAUJ,UAAUK,OACpBH,EAAU,EACVC,EAAU,GAELG,EAAI,EAAGC,EAAM4L,EAAW9L,OAAkBC,EAAIC,EAAKD,IACxDL,EAAWkM,EAAW7L,GACtBH,EAAQG,GAAKL,IAAalB,GAAMmB,EAAUE,EAAUJ,UAAUE,KAAaD,EAG/E,KAAOC,EAAUE,GACbD,EAAQG,KAAON,UAAUE,KAG7B,IAAKI,EAAI,EAAGA,EAAIF,EAASE,IACrB,GAAIN,UAAUM,KAAOvB,EACjB,OAAOkV,EAAW7U,EAAIe,GAI9B,IAAKG,EAAI,EAAGC,EAAMJ,EAAQE,OAAQC,EAAIC,EAAKD,IACnCH,EAAQG,KAAOvB,IACfoB,EAAQG,QAAK,GAIrB,OAAOlB,EAAGW,MAAMjB,KAAMqB,IAiDnB8T,CAAW7U,EAAI,KA2yG1BZ,EAAQW,OAASA,EACjBX,EAAQ0V,KA/lFR,SAAgB7P,EAAWjF,GACvB,OAAO,WACH,OAAOiF,EAAUtE,MAAMjB,KAAMkB,WAAaZ,EAAGW,MAAMjB,KAAMkB,gBAAa,IA8lF9ExB,EAAQ2V,QAtsDR,SAAkB9P,EAAW+P,EAASC,EAAUC,GAC5C,OAAO,SAAU9L,GACb,IAAI+L,EAAY5U,EAAQ8P,GAAW,CAACjH,EAAKzJ,EAAIuV,IAE7C,OAAOjQ,EAAUtE,MAAMyI,EAAK3G,EAAIwS,EAAUE,IAAc,GAAK,CAACH,EAASC,KAmsD/E7V,EAAQc,MAAQA,EAChBd,EAAQkC,YAAcA,EACtBlC,EAAQgW,QAlxGR,SAAkB/I,GACd,IAAK5L,MAAMC,QAAQ2L,GACf,MAAMJ,GAAkBI,EAAW,SAGvC,OAAO,WACH,OAAO5J,EAAI4J,EAAWM,GAAQ/L,cA6wGtCxB,EAAQqC,QAAUA,EAClBrC,EAAQiW,UArkFR,SAAoBpQ,EAAWqQ,EAAQC,GACnC,OAAO,WACH,OAAQtQ,EAAUtE,MAAMjB,KAAMkB,WAAa0U,EAASC,GAAS5U,MAAMjB,KAAMkB,aAokFjFxB,EAAQqF,SAAWA,EACnBrF,EAAQ0F,MAAQA,EAChB1F,EAAQ2F,QAAUA,EAClB3F,EAAQoW,MAtqGR,SAAgBxV,EAAIoK,GAChB,OAAOwC,GAAO5M,EAAIoK,GAAO,IAsqG7BhL,EAAQqW,WAzlGR,SAAqBzV,EAAIoK,GACrB,OAAOwC,GAAO5M,EAAIoK,GAAO,IAylG7BhL,EAAQsW,UA3oGR,SAAoB1V,EAAIoK,GACpB,OAAOwC,GAAO5M,EAAIoK,GAAO,GAAO,IA2oGpChL,EAAQuW,eAnnGR,SAAyB3V,EAAIoK,GACzB,OAAOwC,GAAO5M,EAAIoK,GAAO,GAAM,IAmnGnChL,EAAQwW,SAhkGR,SAAmB5V,EAAI6V,GACnB,IAAIC,EAEJ,OAAO,WACH,IAAItV,EAAOI,UACPmV,EAAY,WACZD,EAAY,KACZ9V,EAAGW,MAAMjB,KAAMc,IACjB0B,KAAKxC,MAEPsW,aAAaF,GACbA,EAAYG,WAAWF,EAAWF,KAsjG1CzW,EAAQ4P,OAASA,GACjB5P,EAAQ8W,WAtwLR,SAAqBpU,EAAWqU,GAC5B,IAAIC,EAAe7V,EAAQ4E,EAAIX,GAAO,CAAC2R,IAEvC,OAAO7Q,EAAQN,EAAOlD,EAAWsU,KAowLrChX,EAAQ6P,OAASA,GACjB7P,EAAQ8P,SAAWA,GACnB9P,EAAQoG,KAAOA,EACfpG,EAAQmG,SAAWA,EACnBnG,EAAQ6G,cAAgBA,EACxB7G,EAAQ8G,UAAYA,EACpB9G,EAAQoR,YAAcA,GACtBpR,EAAQkH,MAAQA,EAChBlH,EAAQiH,QAAUA,EAClBjH,EAAQ4F,OAASA,EACjB5F,EAAQmH,WAAaA,EACrBnH,EAAQsH,KAAOA,EACftH,EAAQqH,UAAYA,EACpBrH,EAAQuH,eAAiBA,EACzBvH,EAAQyH,SAAWA,GACnBzH,EAAQwH,cAAgBA,GACxBxH,EAAQ0H,mBAAqBA,GAC7B1H,EAAQ2H,cAAgBA,GACxB3H,EAAQ4H,UAAYA,GACpB5H,EAAQ6H,QAAUA,GAClB7H,EAAQmI,YAAcA,GACtBnI,EAAQ0I,QAAUA,GAClB1I,EAAQiX,KA9jGR,SAAerW,GACX,OAAO,WACH,IAAIQ,EAAOwI,GAAKrI,MAAM,KAAMC,WAAWsM,UAEvC,OAAOlN,EAAGW,MAAMjB,KAAMc,KA2jG9BpB,EAAQyC,QAAUA,EAClBzC,EAAQkX,UAjrDR,SAAoBC,GAChB,IAAI7T,EAAS,GAMb,OAJAb,EAAQ0U,EAAW,SAAUC,GACzB9T,EAAO8T,EAAK,IAAMA,EAAK,KAGpB9T,GA2qDXtD,EAAQqX,SA3qER,SAAmB/S,EAAOvC,EAAKY,GAG3B,IAFA,IAAIW,EAAS,CAACgB,GAELxC,EAAI,EAAGwV,EAAQvV,EAAM,EAAGD,EAAIwV,EAAOxV,IACxCwB,EAAOwC,KAAKnD,EAASW,EAAOxB,GAAIA,EAAGwB,IAGvC,OAAOA,GAqqEXtD,EAAQ4C,QAAUA,EAClB5C,EAAQuX,SAriGR,SAAmB1T,GACf,OAAO,WACH,OAAOrC,UAAUmH,GAAgB9E,EAAKrC,UAAUK,WAoiGxD7B,EAAQ8I,MAAQA,GAChB9I,EAAQ+J,MAAQA,GAChB/J,EAAQ4I,SAAWA,GACnB5I,EAAQiK,OAASA,GACjBjK,EAAQqR,QAAUA,GAClBrR,EAAQiR,UAAYA,GACpBjR,EAAQ+I,MAAQA,GAChB/I,EAAQgJ,QAAUA,GAClBhJ,EAAQgP,GAAKA,GACbhP,EAAQiP,IAAMA,GACdjP,EAAQsR,IAAMA,GACdtR,EAAQuR,OAASA,GACjBvR,EAAQwX,YA9hDR,SAAsB/R,EAAKrD,GACvB,OAAO,SAAU4H,GACb,OAAOhH,EAAYZ,GAASkP,GAAItH,EAAKvE,IAAQuE,EAAIvE,KAASrD,EAAQ5B,EAAO4B,EAAO4H,EAAIvE,MA6hD5FzF,EAAQwR,OAASA,GACjBxR,EAAQ0R,UAAYA,GACpB1R,EAAQyX,aAv/CR,SAAuB1G,EAAM3O,EAAOoH,GAChC,OAAO,SAAUQ,GACb,IAAIyK,EAAW/D,GAAa1G,EAAK8G,GAAaC,EAAMvH,IAAY,GAEhE,OAAOiL,EAAS5D,SAAWrQ,EAAOiU,EAASrG,OAAQhM,KAo/C3DpC,EAAQiJ,KAAOA,GACfjJ,EAAQmC,SAAWA,EACnBnC,EAAQ6I,MAAQA,GAChB7I,EAAQkJ,QAAUA,GAClBlJ,EAAQmJ,KAAOA,GACfnJ,EAAQoJ,OAASA,GACjBpJ,EAAQsJ,SAAWA,GACnBtJ,EAAQ0X,aAh0JR,SAAuBjX,EAAGC,GACtB,IAAI4C,EAAS,GACTqU,EAAOlX,EAAEoB,OAEb,GAAI8V,GAAQjX,EAAEmB,OACV,IAAK,IAAIC,EAAI,EAAGA,EAAI6V,EAAM7V,KACrBsD,EAAK9B,EAAQ7C,EAAEqB,KAAOsD,EAAK1E,EAAGD,EAAEqB,KAAOwB,EAAOwC,KAAKrF,EAAEqB,IAI9D,OAAOwB,GAuzJXtD,EAAQ4X,QAr/FR,SAAkB1J,EAAYC,GAC1B,OAAOhN,EAAQ8M,GAAU,CAACC,EAAYC,KAq/F1CnO,EAAQ6X,UA99FR,SAAoBzJ,GAChB,OAAOjN,EAAQ8M,GAAU,CAAC1N,EAAI,GAAI6N,KA89FtCpO,EAAQkP,GAAKA,GACblP,EAAQ8X,SA5qER,SAAoB1V,GAChB,MAAuB,WAAhB4C,EAAK5C,IAAuB0V,SAAS1V,IA4qEhDpC,EAAQmP,KAAOA,GACfnP,EAAQoP,MAAQA,GAChBpP,EAAQoF,KAAOA,EACfpF,EAAQ+X,aAvHR,SAAuBC,GACnB,OAAO,SAAUhO,GACb,OAAOA,aAAegO,IAsH9BhY,EAAQ+P,UAAYA,GACpB/P,EAAQsP,KAAOA,GACftP,EAAQwP,MAAQA,GAChBxP,EAAQiD,MAAQA,EAChBjD,EAAQ+C,OAASA,EACjB/C,EAAQoD,MAAQA,EAChBpD,EAAQiY,cAjoER,SAAwB7V,GACpB,OAAO2N,GAAU3N,IAAU8B,KAAKE,IAAIhC,IAAUG,GAioElDvC,EAAQkY,OA1GR,SAAiBC,GACb,OAAO,SAAU/V,GACb,OAAO4C,EAAK5C,KAAW+V,IAyG/BnY,EAAQgD,YAAcA,EACtBhD,EAAQuJ,KAAOA,GACfvJ,EAAQ0J,SAAWA,GACnB1J,EAAQoY,aAl9CR,SAAuBvS,EAAWJ,GAC9B,OAAO,SAAUuE,GACb,OAAOnE,EAAUhF,KAAKP,KAAM0J,EAAIvE,MAi9CxCzF,EAAQ2R,KAAOA,GACf3R,EAAQ2J,KAAOA,GACf3J,EAAQ4J,KAAOA,GACf5J,EAAQqP,GAAKA,GACbrP,EAAQuP,IAAMA,GACdvP,EAAQ4R,KAAOA,GACf5R,EAAQqD,IAAMA,EACdrD,EAAQqY,QA79FR,SAAkBzX,EAAI0X,GAClB,OAAOtL,GAAK,CAACpD,GAAMrG,EAAQ+U,GAAS/W,GAAMX,MA69F9CZ,EAAQ+R,UAAYA,GACpB/R,EAAQiS,cAAgBA,GACxBjS,EAAQuD,QAAUA,EAClBvD,EAAQmS,MAAQA,GAChBnS,EAAQoS,SAAWA,GACnBpS,EAAQuY,OA1nER,SAAiB9X,EAAGC,GAChB,OAAOD,EAAKC,EAAIwD,KAAKC,MAAM1D,EAAIC,IA0nEnCV,EAAQgQ,SAAWA,GACnBhQ,EAAQiQ,WAAaA,GACrBjQ,EAAQ+F,IAAMA,EACd/F,EAAQuS,SAAWA,GACnBvS,EAAQyS,UAAYA,GACpBzS,EAAQwY,QAxQR,SAAkBxG,EAAQkD,EAAMnT,GAC5B,OAAOkT,GAAYjD,EAAQkD,EAAMnT,GAAOiQ,GAwQ5ChS,EAAQyY,SAjPR,SAAmBzG,EAAQkD,EAAMnT,GAC7B,OAAOiQ,EAASiD,GAAYjD,EAAQkD,EAAMnT,IAiP9C/B,EAAQ0S,MAAQA,GAChB1S,EAAQmB,QAAUA,EAClBnB,EAAQ0Y,aAn4MR,SAAuB9X,EAAIQ,GACvB,OAAO,WACH,IAAKC,MAAMC,QAAQF,GACf,OAAOR,EAAGW,MAAMjB,KAAMkB,WAQ1B,IALA,IAK0BC,EALtBC,EAAUF,UAAUK,OAAS,EAC7BD,EAAUR,EAAKS,OACfsM,EAAY9M,MAAMO,GAClBD,EAAU,GAELG,EAAIF,EAAU,EAAaE,GAAK,EAAGA,IACxCL,EAAWL,EAAKU,GAChBqM,EAAUrM,GAAKL,IAAalB,EAAKiB,UAAUE,KAAaD,EAG5D,IAAKK,EAAI,EAAGA,GAAKJ,EAASI,IACtBH,EAAQG,GAAKN,UAAUM,GAG3B,IAAK,IAAI0G,EAAI,EAAGA,EAAI5G,EAAS4G,IACzB7G,EAAQG,KAAOqM,EAAU3F,GAG7B,OAAO5H,EAAGW,MAAMjB,KAAMqB,KA42M9B3B,EAAQ6J,UAAYA,GACpB7J,EAAQ8J,cAAgBA,GACxB9J,EAAQ4S,WAAaA,GACrB5S,EAAQ2S,aAAeA,GACvB3S,EAAQ2Y,cA/nCR,SAAwB9S,EAAWkL,EAAMvH,GACrC,OAAO,SAAUQ,GACb,IAAIyK,EAAW/D,GAAa1G,EAAK8G,GAAaC,EAAMvH,IAAY,GAEhE,OAAO3D,EAAUhF,KAAKP,KAAMmU,EAASrG,UA4nC7CpO,EAAQ6S,KAAOA,GACf7S,EAAQ+S,OAASA,GACjB/S,EAAQgT,SAAWA,GACnBhT,EAAQgN,KAAOA,GACfhN,EAAQ4Y,MAnnJR,SAAgBlW,EAAW+C,GACvB,OAAOpC,EAAIX,EAAWuH,GAAOxE,KAmnJjCzF,EAAQkK,SAAWA,GACnBlK,EAAQqK,KAAOA,GACfrK,EAAQmK,SAAWA,GACnBnK,EAAQ6Y,UA5lER,SAAoB7X,EAAKC,GACrB,OAAOiD,KAAKC,MAAMD,KAAK4U,UAAY7X,EAAMD,EAAM,GAAKA,IA4lExDhB,EAAQ+Y,MAnjER,SAAgBzU,EAAOgT,EAAO7T,GAK1B,GAJAa,EAAQ4L,GAAe5L,GACvBgT,EAAQpH,GAAeoH,GAGV,KAFb7T,EAA4B,IAArBjC,UAAUK,OAAeqO,GAAezM,GAAQ,GAGnD,OAAO6T,IAAUhT,EAAQ,GAAK,CAACA,GAMnC,IAHA,IAAIvC,EAAMmC,KAAKjD,IAAIiD,KAAKiR,MAAMmC,EAAQhT,GAASb,GAAO,GAClDH,EAASjC,MAAMU,GAEVD,EAAI,EAAG6H,EAAOrF,EAAOxC,EAAIC,EAAKD,IACnCwB,EAAOxB,GAAK6H,EACZA,GAAQlG,EAGZ,OAAOH,GAmiEXtD,EAAQ+D,OAASA,EACjB/D,EAAQsK,YAAcA,GACtBtK,EAAQuK,gBAAkBA,GAC1BvK,EAAQgE,WAAaA,EACrBhE,EAAQgZ,UAjhER,SAAoBvY,EAAGC,GACnB,OAAOD,EAAIC,GAihEfV,EAAQiT,OAASA,GACjBjT,EAAQqT,WAAaA,GACrBrT,EAAQiZ,WA57BR,SAAqBrY,GACjB,OAAO,SAAUoR,GACb,OAAOiB,GAAOjB,EAAQpR,EAAGoR,MA27BjChS,EAAQkZ,OAtPR,SAAiBlH,EAAQgD,GACrB,GAAI/R,EAAM+O,GACN,MAAMnF,GAAkBmF,EAAQ,UAGpC,OAAO+C,GAAQ/C,EAAQ9N,KAAKC,MAAM6Q,KAkPtChV,EAAQ8N,QAt/IR,SAAkBpL,GAId,IAHA,IAAIX,EAAMS,EAAeE,EAAUb,QAC/ByB,EAASjC,MAAMU,GAEVD,EAAI,EAAG2M,EAAM1M,EAAM,EAAGD,EAAIC,EAAKD,IACpCwB,EAAOxB,GAAKY,EAAU+L,EAAM3M,GAGhC,OAAOwB,GA++IXtD,EAAQwK,OAASA,GACjBxK,EAAQ2K,SAAWA,GACnB3K,EAAQ8K,MAAQA,GAChB9K,EAAQuT,MAAQA,GAChBvT,EAAQiL,SAAWA,GACnBjL,EAAQwT,OAASA,GACjBxT,EAAQmZ,QAhvBR,SAAkBpI,EAAM3O,EAAOoH,GAC3B,OAAO,SAAUwI,GACb,OAAO6B,GAAU7B,EAAQjB,EAAM3O,EAAOoH,KA+uB9CxJ,EAAQ6T,UAAYA,GACpB7T,EAAQkL,eAAiBA,GACzBlL,EAAQ8T,KAAOA,GACf9T,EAAQiU,OAASA,GACjBjU,EAAQkU,SAAWA,GACnBlU,EAAQqE,MAAQA,EAChBrE,EAAQ2E,QAAUA,EAClB3E,EAAQoL,KAAOA,GACfpL,EAAQmL,OAASA,GACjBnL,EAAQiM,KAAOA,GACfjM,EAAQoM,SAAWA,GACnBpM,EAAQoZ,aAjhIR,SAAuB1W,EAAW8C,EAASwG,GACvC,IAAI1I,EAASe,EAAM3B,EAAW,EAAGA,EAAUb,QAE3C,GAAyB,IAArBL,UAAUK,OACV,OAAOyB,EAGX,IACIO,EA5ER,SAASwV,EAAoBvR,EAAOtC,EAASqG,EAAUvH,EAAOC,GAC1D,GAAqB,IAAjBuD,EAAMjG,OACN,OAAO,EAGX,IAAIyX,EAAShV,EAAQC,GAAQ,EACzBjB,EAASuI,EACT,CAAEzJ,MAAOoD,EAASqD,MAAOyQ,GACzB,CAAElX,MAAO0F,EAAMwR,GAAQzQ,MAAOyQ,IAGlC,OAAI/U,EAAMD,GAAS,EACRhB,EAAS,EAAIgW,EAAQA,EAAQ,EAC7BhW,EAAS,EACT+V,EAAmBvR,EAAOtC,EAASqG,EAAUvH,EAAOgV,GACzC,IAAXhW,EACAgW,EAAQ,EAERD,EAAmBvR,EAAOtC,EAASqG,EAAUyN,EAAO/U,GA0DrD8U,CAAmB/V,EAAQkC,EAAS6F,GAD/BU,GAAcC,IACyC,EAAG1I,EAAOzB,QAIhF,OAFAyB,EAAO+F,OAAOxF,EAAK,EAAG2B,GAEflC,GAsgIXtD,EAAQkM,OAASA,GACjBlM,EAAQmM,WAAaA,GACrBnM,EAAQ2P,SAAWA,GACnB3P,EAAQyP,IAAMA,GACdzP,EAAQqM,KAAOA,GACfrM,EAAQuM,KAAOA,GACfvM,EAAQsM,SAAWA,GACnBtM,EAAQwM,cAAgBA,GACxBxM,EAAQyM,UAAYA,GACpBzM,EAAQuZ,QA5gGR,SAAkB3Y,EAAI4Y,GAClB,OAAO,WAKH,IAJA,IAAIzX,EAAMP,UAAUK,OAChB4X,EAAaD,EAAQ3X,OACrBT,EAAO,GAEFU,EAAI,EAAGA,EAAIC,EAAKD,IACrBV,EAAK0E,KAAKhE,EAAI2X,EAAaD,EAAQ1X,GAAGN,UAAUM,IAAMN,UAAUM,IAGpE,OAAOlB,EAAGW,MAAMjB,KAAMc,KAmgG9BpB,EAAQoU,KAAOA,GACfpU,EAAQqU,QAAUA,GAClBrU,EAAQ0Z,SAvPR,SAAmBC,GACf,OAAO,SAAUC,GACb,OAAgC,IAAzBxE,GAAQwE,EAAGD,KAsP1B3Z,EAAQ6Z,SA9+FR,SAAmBjZ,EAAI6V,GACnB,IAAInT,EACAwW,EAAW,EAEf,OAAO,WACH,IAAIC,EAAMC,KAAKD,MAOf,OALIA,EAAMD,GAAYrD,IAClBqD,EAAWC,EACXzW,EAAS1C,EAAGW,MAAMjB,KAAMkB,YAGrB8B,IAm+FftD,EAAQ0M,UAAYA,GACpB1M,EAAQgF,KAAOA,EACfhF,EAAQia,MAh9FR,SAAgBrZ,GACZ,OAAO,SAAUH,GACb,OAAOG,EAAGC,KAAKP,KAAMG,KA+8F7BT,EAAQmN,MAAQA,GAChBnN,EAAQkN,QAAUA,GAClBlN,EAAQkG,QAAUA,EAClBlG,EAAQgG,UAAYA,EACpBhG,EAAQka,OAt9ER,SAAiBrU,EAAWjF,GACxB,OAAO,SAAUwB,GACb,OAAOyD,EAAUhF,KAAKP,KAAM8B,GAASA,EAAQxB,EAAGC,KAAKP,KAAM8B,KAq9EnEpC,EAAQma,SArrHR,SAAmBtR,EAAOgC,GACtB,OAAO,SAAUnI,GACb,OAAOkI,GAAUlI,EAAWmG,EAAO,KAAMgC,KAorHjD7K,EAAQsU,SAAWA,GACnBtU,EAAQoN,YAAcA,GACtBpN,EAAQuU,UAAYA,GACpBvU,EAAQoa,WAzeR,SAAqBrJ,EAAMlG,EAASrB,GAChC,OAAO,SAAUwI,GACb,OAAOwC,GAAaxC,EAAQjB,EAAMlG,EAASrB,KAwenDxJ,EAAQwU,aAAeA,GACvBxU,EAAQ0U,SAAWA,GACnB1U,EAAQ8U,aAAeA,GACvB9U,EAAQoK,OAASA,GACjBpK,EAAQqa,KAj8ER,SAAexU,EAAWjF,GACtB,OAAO,SAAUwB,GACb,OAAOyD,EAAUhF,KAAKP,KAAM8B,GAASxB,EAAGC,KAAKP,KAAM8B,GAASA,IAg8EpEpC,EAAQsa,IA1oHR,SAAc7Z,EAAGC,GACb,OAAOgM,GAAU,CAACjM,EAAGC,KA0oHzBV,EAAQqN,aAAeA,GAEvBxI,OAAO0V,eAAeva,EAAS,aAAc,CAAEoC,OAAO","file":"lamb.min.js","sourcesContent":["/**\n* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n* @author Andrea Scartabelli \n* @version 0.58.0-alpha.9\n* @module lamb\n* @license MIT\n*/\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (global = global || self, factory(global.lamb = {}));\n}(this, function (exports) { 'use strict';\n\n /**\n * The placeholder object used in partial application.\n * @memberof module:lamb\n * @alias module:lamb.__\n * @category Special properties\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.57.0\n * @type {Object}\n */\n var __ = {};\n\n /**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n function always (value) {\n return function () {\n return value;\n };\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n }\n\n /**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n }\n\n /**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n }\n\n /**\n * Builds a partially applied function.
\n * The {@link module:lamb.__|__} object can be used as a placeholder for arguments.
\n * @example\n * var __ = _.__;\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [__, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\n function partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = boundArg === __ ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\n function _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [__, a, b]);\n };\n }\n\n /**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\n var clampWithin = _makePartial3(clamp);\n\n /**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\n function identity (value) {\n return value;\n }\n\n /**\n * Returns a function that is the composition of the functions given as parameters.\n * The first function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {Function} a\n * @param {Function} b\n * @returns {Function}\n */\n function compose (a, b) {\n return arguments.length ? function () {\n return a.call(this, b.apply(this, arguments));\n } : identity;\n }\n\n var MAX_ARRAY_LENGTH = 4294967295;\n var MAX_SAFE_INTEGER = 9007199254740991;\n\n /**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n }\n\n /* eslint-disable jsdoc/require-returns-check */\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\n function forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n }\n\n /**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\n var generic = Function.bind.bind(Function.call);\n\n /**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNull (value) {\n return value === null;\n }\n\n /**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n return value === void 0;\n }\n\n /**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNil (value) {\n return isNull(value) || isUndefined(value);\n }\n\n /**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n }\n\n /**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var isSVZ = _curry2(areSVZ);\n\n /**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\n var mapWith = _curry2(map, true);\n\n /**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var __ = _.__;\n * var f1 = _.partial(_.list, [\"a\", __, __, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", __, __, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\n function partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = boundArg === __ ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\n function _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n }\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = _makeReducer(1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceWith = _makePartial3(reduce, true);\n\n /**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n }\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n function slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n }\n\n /**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\n var sliceAt = _makePartial3(slice);\n\n var objectProtoToString = Object.prototype.toString;\n\n /**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return objectProtoToString.call(value).slice(8, -1);\n }\n\n /**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\n function appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n }\n\n /**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\n var append = _curry2(appendTo, true);\n\n /**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\n function isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\n var contains = _curry2(isIn, true);\n\n /**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\n function _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n }\n\n /**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var count = _groupWith(function (a) {\n return a ? ++a : 1;\n });\n\n /**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter([_.getKey(\"city\"), _.always(\"Unknown\")]);\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var countBy = _curry2(count, true);\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\n function filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n }\n\n /**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n }\n\n /**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n\n for (var i = 0, len = arrayLike.length, seen = [], value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n };\n }\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var uniques = uniquesBy(identity);\n\n /**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.pull|pull}, {@link module:lamb.pullFrom|pullFrom}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\n function difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n }\n\n /**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var drop = _curry2(dropFrom, true);\n\n /**\n * Gets the index of the last element satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\n function _getLastHitIndex (arrayLike, predicate, fromLast) {\n var idx;\n var increment;\n var len = arrayLike.length;\n\n if (fromLast) {\n idx = len - 1;\n increment = -1;\n } else {\n idx = 0;\n increment = 1;\n }\n\n while (idx >= 0 && idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx += increment;\n }\n\n return idx;\n }\n\n /**\n * Helper to build the {@link module:lamb.takeWhile|takeWhile},\n * {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropWhile|dropWhile} and\n * {@link module:lamb.dropLastWhile|dropLastWhile} functions.\n * @private\n * @param {Boolean} isTake\n * @param {Boolean} fromLast\n * @returns {Function}\n */\n function _takeOrDropWhile (isTake, fromLast) {\n return function (predicate) {\n return function (arrayLike) {\n var idxFrom;\n var idxTo;\n var lastHitIndex = _getLastHitIndex(arrayLike, predicate, fromLast);\n\n if (isTake && fromLast) {\n idxFrom = lastHitIndex + 1;\n idxTo = arrayLike.length;\n } else if (isTake) {\n idxFrom = 0;\n idxTo = lastHitIndex;\n } else if (!isTake && fromLast) {\n idxFrom = 0;\n idxTo = lastHitIndex + 1;\n } else {\n idxFrom = lastHitIndex;\n idxTo = arrayLike.length;\n }\n\n return slice(arrayLike, idxFrom, idxTo);\n };\n };\n }\n\n /**\n * Builds a function that drops the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropLastWhileIsEven = _.dropLastWhile(isEven);\n *\n * dropLastWhileIsEven([2, 4, 6, 8]) // => []\n * dropLastWhileIsEven([2, 4, 7, 8]) // => [2, 4, 7]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var dropLastWhile = _takeOrDropWhile(false, true);\n\n /**\n * Builds a function that drops the first elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var dropWhile = _takeOrDropWhile(false, false);\n\n /**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\n function _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n }\n\n /**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var everyIn = _makeArrayChecker(true);\n\n /**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var every = _curry2(everyIn, true);\n\n /**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var filterWith = _curry2(filter, true);\n\n /**\n * Helper to create the {@link module:lamb.findIndex|findIndex} and\n * {@link module:lamb.findLastIndex|findLastIndex} functions.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\n function _findIndex (arrayLike, predicate, fromLast) {\n var start;\n var increment;\n var len = arrayLike.length;\n var result = -1;\n\n if (fromLast) {\n start = len - 1;\n increment = -1;\n } else {\n start = 0;\n increment = 1;\n }\n\n for (var i = start; i < len && i >= 0; i += increment) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, false);\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 6, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findIndexWhere = _curry2(findIndex, true);\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object starting from\n * the end and returns its index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 40)) // => 3\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findLastIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, true);\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object starting from the end\n * and returns it if the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLast(persons, _.hasKeyValue(\"surname\", \"Doe\")) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.findLast(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function findLast (arrayLike, predicate) {\n var idx = findLastIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * A curried version of {@link module:lamb.findLastIndex|findLastIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findLastEvenIdx = _.findLastIndexWhere(isEven);\n *\n * findLastEvenIdx([1, 3, 4, 5, 6, 7]) // => 4\n * findLastEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastIndex|findLastIndex}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findLastIndexWhere = _curry2(findLastIndex, true);\n\n /**\n * A curried version of {@link module:lamb.findLast|findLast} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findLastWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 6, 7]) // => 6\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findLastWhere = _curry2(findLast, true);\n\n /**\n * A curried version of {@link module:lamb.find|find} expecting the array-like object\n * to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findWhere = _curry2(find, true);\n\n /**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var flatMapWith = _curry2(flatMap, true);\n\n /**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\n function _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n }\n\n /**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\n var _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n });\n\n /**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\n var flatten = _makeArrayFlattener(true);\n\n /**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\n function _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n }\n\n /**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\n function getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\n var getAt = _curry2(getIndex, true);\n\n /**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter([getCity, _.always(\"Unknown\")]);\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n });\n\n /**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var groupBy = _curry2(group, true);\n\n /**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\n\n /**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var index = _groupWith(function (a, b) {\n return b;\n });\n\n /**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var indexBy = _curry2(index, true);\n\n /**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, [__, 0, -1]);\n\n /**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\n function insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\n var insertAt = _makePartial3(insert);\n\n /**\n * Returns an array of every unique item that is included in all two given arrays\n * or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function intersection (a, b) {\n var result = [];\n var lenA = a.length;\n\n if (lenA && b.length) {\n for (var i = 0; i < lenA; i++) {\n !isIn(result, a[i]) && isIn(b, a[i]) && result.push(a[i]);\n }\n }\n\n return result;\n }\n\n /**\n * Transforms an array-like object into a string by joining its elements with\n * the given separator.
\n * Note that unlike the native method, this function won't convert\n * null and undefined values in the array to empty\n * strings and that the separator parameter isn't optional.
\n * See the examples about these differences.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n *\n * _.join(words, \"-\") // => \"foo-bar-baz\"\n *\n * @example Showing the differences with the native array method:\n * var mixed = [1, null, 2, undefined, 3, NaN, 4, 5];\n * var numbers = [1, 2, 3];\n *\n * _.join(mixed, \"-\") // => \"1-null-2-undefined-3-NaN-4-5\"\n * mixed.join(\"-\") // => \"1--2--3-NaN-4-5\"\n *\n * _.join(numbers) // => \"1undefined2undefined3\"\n * numbers.join() // => \"1,2,3\"\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.joinWith|joinWith}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {String} separator\n * @returns {String}\n */\n function join (arrayLike, separator) {\n return map(arrayLike, String).join(String(separator));\n }\n\n /**\n * A curried version of {@link module:lamb.join|join} that accepts an optional\n * separator and builds a function expecting the array-like object to act upon.
\n * Please refer to the description and examples of {@link module:lamb.join|join}\n * to understand the differences with the native array method.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n * var joinWithDash = _.joinWith(\"-\");\n *\n * joinWithDash(words) // => \"foo-bar-baz\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.join|join}\n * @since 0.58.0\n * @param {String} separator\n * @returns {Function}\n */\n var joinWith = _curry2(join, true);\n\n /**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\n function _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n }\n\n /**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\n var list = _argsToArrayFrom(0);\n\n /**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\n function partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var partitionWith = _curry2(partition, true);\n\n /**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\n }\n\n /**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry2(getIn, true);\n\n /**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\n function pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n }\n\n /**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\n var pluckKey = compose(mapWith, getKey);\n\n /**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @example It's not the same as {@link module:lamb.difference|difference}:\n *\n * var arr = [1,1,2,3,4,4,5];\n *\n * _.pullFrom(arr, [1, 2]) // => [3, 4, 4, 5]\n * _.difference(arr, [1, 2]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\n function pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * See examples in {@link module:lamb.pullFrom|pullFrom} about the\n * relationship with {@link module:lamb.difference|difference}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\n var pull = _curry2(pullFrom, true);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = _makeReducer(-1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceRightWith = _makePartial3(reduceRight, true);\n\n /**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n }\n\n /**\n * Returns a copy of the given array-like with the element rotated by the desired amount.\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.rotate(arr, 3) // => [3, 4, 5, 1, 2]\n * _.rotate(arr, -3) // => [4, 5, 1, 2, 3]\n * _.rotate(arr, 11) // => [5, 1, 2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.rotateBy|rotateBy}\n * @since 0.55.0\n * @param {ArrayLike} arrayLike\n * @param {Number} amount\n * @returns {Array}\n */\n function rotate (arrayLike, amount) {\n var len = arrayLike.length;\n var shift = amount % len;\n\n return slice(arrayLike, -shift, len).concat(slice(arrayLike, 0, -shift));\n }\n\n /**\n * A curried version of {@link module:lamb.rotate|rotate}.
\n * Uses the given amount to build a function expecting the array to rotate by that amount.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var rotateByTwo = _.rotateBy(2);\n *\n * rotateByTwo(arr) // => [4, 5, 1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.rotate|rotate}\n * @since 0.55.0\n * @param {Number} amount\n * @returns {Function}\n */\n var rotateBy = _curry2(rotate, true);\n\n /**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\n function _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n var setAt = _makePartial3(_setIndex);\n\n /**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\n var setIndex = aritize(_setIndex, 3);\n\n /**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\n var shallowFlatten = _makeArrayFlattener(false);\n\n /**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var someIn = _makeArrayChecker(false);\n\n /**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var some = _curry2(someIn, true);\n\n /**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\n function _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n }\n\n /**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\n function _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n if (!areSVZ(a, b)) {\n // eslint-disable-next-line no-self-compare\n result = a > b || a !== a ? 1 : -1;\n }\n\n return result;\n }\n\n /**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\n function _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n }\n\n /**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\n function _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n /**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\n function _makeCriteria (sorters) {\n return sorters && sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n }\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, [_.getKey(\"name\")]);\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(persons, [\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * ]);\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, [localeSorter]) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, [localeSorterDesc]) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Array}\n */\n function sort (arrayLike, sorters) {\n var criteria = _makeCriteria(sorters);\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = { value: arrayLike[i], index: i };\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n }\n\n /**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\n function _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n { value: element, index: pivot },\n { value: array[pivot], index: pivot }\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\n function sortedInsert (arrayLike, element, sorters) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorter = partial(_sorter, [__, false, __]);\n\n /**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorterDesc = partial(_sorter, [__, true, __]);\n\n /**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith([parseFloat]);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Function}\n */\n var sortWith = _curry2(sort, true);\n\n /**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = drop(1);\n\n /**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n }\n\n /**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\n var take = _curry2(takeFrom, true);\n\n /**\n * Builds a function that takes the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeLastWhileIsEven = _.takeLastWhile(isEven);\n *\n * takeLastWhileIsEven([1, 3, 5, 7]) // => []\n * takeLastWhileIsEven([2, 3, 6, 8]) // => [6, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var takeLastWhile = _takeOrDropWhile(true, true);\n\n /**\n * Builds a function that takes the first elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var takeWhile = _takeOrDropWhile(true, false);\n\n /**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\n function _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n }\n\n /**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var __ = _.__;\n * var square = _.partial(Math.pow, [__, 2]);\n * var getMaxAndSquare = _.pipe([Math.max, square]);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function pipe (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n var len = functions.length;\n\n return len ? function () {\n var result = functions[0].apply(this, arguments);\n\n for (var i = 1; i < len; i++) {\n result = functions[i].call(this, result);\n }\n\n return result;\n } : identity;\n }\n\n /**\n * Using the provided iteratee to transform values, builds a function that will\n * return an array of the unique elements in the two provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to compare transformed values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function unionBy (iteratee) {\n return pipe([binary(list), flatMapWith(drop(0)), uniquesBy(iteratee)]);\n }\n\n /**\n * Returns a list of every unique element present in the two given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [2, 3, 4]) // => [1, 2, 3, 4]\n * _.union(\"abc\", \"bcd\") // => [\"a\", \"b\", \"c\", \"d\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n var union = unionBy(identity);\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\n function updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\n var updateIndex = partial(_setIndex, [__, __, null, __]);\n\n /**\n * Builds a list of arrays out of the two given array-like objects by pairing items with\n * the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3]\n * ) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function zip (a, b) {\n return transpose([a, b]);\n }\n\n /**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n /**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function application (fn, args) {\n return fn.apply(this, Object(args));\n }\n\n /**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n var apply = _curry2(application);\n\n /**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyTo = _curry2(application, true);\n\n /**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\n function _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === __ && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === __) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === __) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, __, 2)(3) // => 9\n * f(__, 3, __)(4, __)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, __);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, __);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\n function asPartial (fn) {\n return _asPartial(fn, []);\n }\n\n /**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect([_.getKey(\"id\"), _.getPath(\"scores.-1\")]);\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect([Math.min, Math.max]);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function collect (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n }\n\n /**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\n function _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n }\n\n /**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n }\n\n /**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n }\n\n /**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curry (fn, arity) {\n return _curry(fn, arity, false);\n }\n\n /**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n }\n\n /**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n }\n\n /**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryRight (fn, arity) {\n return _curry(fn, arity, true);\n }\n\n /**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\n function debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = _.getArgAt(0);\n * var getLastArg = _.getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * _.getArgAt()(1, 2, 3) // => undefined\n * _.getArgAt(6)(1, 2, 3) // => undefined\n * _.getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\n function getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n }\n\n /* eslint-disable jsdoc/check-param-names */\n\n /**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * received by {@link module:lamb.invoker|invoker}, with the final set of args,\n * if present.\n * @private\n * @param {String} methodName\n * @param {Array} boundArgs\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\n function _invoker (methodName, boundArgs, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs ? _toArrayLength(boundArgs.length) : 0;\n var finalArgsLen = boundArgsLen + arguments.length - 3;\n var finalArgs = Array(finalArgsLen);\n\n for (var i = 0; i < boundArgsLen; i++) {\n finalArgs[i] = boundArgs[i];\n }\n\n for (var ofs = 3 - i; i < finalArgsLen; i++) {\n finalArgs[i] = arguments[i + ofs];\n }\n\n return method.apply(target, finalArgs);\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", [2]);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {ArrayLike} [boundArgs=[]]\n * @returns {Function}\n */\n function invoker (methodName, boundArgs) {\n return partial(_invoker, [methodName, boundArgs]);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return partial(_invoker, [__, [], target]);\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var __ = _.__;\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [__, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return pipe([list, mapWith(mapper), apply(fn)]);\n }\n\n /**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\n function tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\n function throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n }\n\n /**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in synergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.invoker(\"join\", [\"\"]), _.filter);\n * var filterAdapter = _.adapter([\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * ]);\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // by its nature is composable\n * var filterWithDefault = _.adapter([filterAdapter, _.always(\"Not implemented\")]);\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function adapter (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Creates a function to check the given predicates.
\n * Used to build the {@link module:lamb.allOf|allOf} and the\n * {@link module:lamb.anyOf|anyOf} functions.\n * @private\n * @param {Boolean} checkAll\n * @returns {Function}\n */\n function _checkPredicates (checkAll) {\n return function (predicates) {\n if (!Array.isArray(predicates)) {\n throw _makeTypeErrorFor(predicates, \"array\");\n }\n\n return function () {\n for (var i = 0, len = predicates.length, result; i < len; i++) {\n result = predicates[i].apply(this, arguments);\n\n if (checkAll && !result) {\n return false;\n } else if (!checkAll && result) {\n return true;\n }\n }\n\n return checkAll;\n };\n };\n }\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the array will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf([isEven, _.isGT(0)]);\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var allOf = _checkPredicates(true);\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the array will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf([isInGroup(\"admin\"), isInGroup(\"root\")]);\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var anyOf = _checkPredicates(false);\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n }\n\n /**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions\n * and {@link module:lamb.unless|unless} and {@link module:lamb.when|when} where one of the branches\n * is the identity function.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @alias module:lamb.case\n * @category Logic\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\n function condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n }\n\n /**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gt (a, b) {\n return a > b;\n }\n\n /**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gte (a, b) {\n return a >= b;\n }\n\n /**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var is = _curry2(areSame);\n\n /**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGT = _curry2(gt, true);\n\n /**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGTE = _curry2(gte, true);\n\n /**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lt (a, b) {\n return a < b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLT = _curry2(lt, true);\n\n /**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lte (a, b) {\n return a <= b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLTE = _curry2(lte, true);\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n }\n\n /**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function sum (a, b) {\n return a + b;\n }\n\n /**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\n var add = _curry2(sum, true);\n\n /**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n /**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var deduct = _curry2(subtract, true);\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function divide (a, b) {\n return a / b;\n }\n\n /**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var divideBy = _curry2(divide, true);\n\n /**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @alias module:lamb.isFinite\n * @category Math\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n }\n\n /**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n }\n\n /**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function modulo (a, b) {\n return a - (b * Math.floor(a / b));\n }\n\n /**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\n\n /**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var multiplyBy = _curry2(multiply, true);\n\n /**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n }\n\n /**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n }\n\n /**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function remainder (a, b) {\n return a % b;\n }\n\n /**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var _isOwnEnumerable = generic(Object.prototype.propertyIsEnumerable);\n\n /**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\n function _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n }\n\n /**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n }\n\n /**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\n function _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n }\n\n /**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\n function _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? { isValid: true, target: target } : { isValid: false, target: void 0 };\n }\n\n /**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\n function _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n }\n\n /**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n }\n\n /**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.areSame,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\n function checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, __, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n });\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\n var enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var getPath = _makePartial3(getPathIn);\n\n /**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n }\n\n /**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry2(has, true);\n\n /**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var hasOwn = generic(Object.prototype.hasOwnProperty);\n\n /**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry2(hasOwn, true);\n\n /**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n }\n\n /**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n }\n\n /**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\n var _safeKeys = compose(Object.keys, Object);\n\n /**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\n var keys = _unsafeKeyListFrom(_safeKeys);\n\n /**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\n function keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n }\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\n function make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\n\n /**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\n function mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\n var mapValuesWith = _curry2(mapValues, true);\n\n /**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {Object} a\n * @param {Object} b\n * @returns {Function}\n */\n function _merge (getKeys, a, b) {\n return reduce([a, b], function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n /**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy the last source has precedence over the first.\n * @example\n * _.merge({a: 1, b: 3}, {b: 5, c: 4}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99) // => {a: 2}\n * _.merge({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var merge = partial(_merge, [enumerables]);\n\n /**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99) // => {a: 2}\n * _.mergeOwn({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, [keys]);\n\n /**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\n var _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n });\n\n /**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n });\n\n /**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(keys);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), function (key) {\n return obj[key];\n });\n });\n\n /**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(keys);\n\n /**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var pairs = _pairsFrom(enumerables);\n\n /**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\n function pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var pathExists = _makePartial3(pathExistsIn);\n\n /**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n }\n\n /**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n function pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\n var pickKeys = _curry2(pick, true);\n\n /**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\n function rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\n var renameKeys = _curry2(rename, true);\n\n /**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\n function renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n }\n\n /**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n }\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var setKey = _makePartial3(setIn);\n\n /**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\n function _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n }\n\n /**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\n function _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n }\n\n /**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n }\n\n /**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n var skipIf = compose(pickIf, not);\n\n /**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\n var skipKeys = _curry2(skip, true);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n });\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tear = _tearFrom(enumerables);\n\n /**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tearOwn = _tearFrom(keys);\n\n /**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\n function updateIn (source, key, updater) {\n return _isEnumerable(source, key)\n ? _setIn(source, key, updater(source[key]))\n : _merge(enumerables, source, {});\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n var updateKey = _makePartial3(updateIn);\n\n /**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source, {});\n }\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n }\n\n /**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry2(validate, true);\n\n /**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n /**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n }\n\n /**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\n function _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n }\n\n /**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n }\n\n /**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\n var _search = generic(String.prototype.search);\n\n /**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n }\n\n /**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\n function isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n }\n\n /**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\n function isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n }\n\n exports.__ = __;\n exports.adapter = adapter;\n exports.add = add;\n exports.allOf = allOf;\n exports.always = always;\n exports.anyOf = anyOf;\n exports.append = append;\n exports.appendTo = appendTo;\n exports.application = application;\n exports.apply = apply;\n exports.applyTo = applyTo;\n exports.areSVZ = areSVZ;\n exports.areSame = areSame;\n exports.aritize = aritize;\n exports.asPartial = asPartial;\n exports.binary = binary;\n exports.case = case_;\n exports.checker = checker;\n exports.clamp = clamp;\n exports.clampWithin = clampWithin;\n exports.collect = collect;\n exports.compose = compose;\n exports.condition = condition;\n exports.contains = contains;\n exports.count = count;\n exports.countBy = countBy;\n exports.curry = curry;\n exports.curryRight = curryRight;\n exports.curryable = curryable;\n exports.curryableRight = curryableRight;\n exports.debounce = debounce;\n exports.deduct = deduct;\n exports.difference = difference;\n exports.divide = divide;\n exports.divideBy = divideBy;\n exports.drop = drop;\n exports.dropFrom = dropFrom;\n exports.dropLastWhile = dropLastWhile;\n exports.dropWhile = dropWhile;\n exports.enumerables = enumerables;\n exports.every = every;\n exports.everyIn = everyIn;\n exports.filter = filter;\n exports.filterWith = filterWith;\n exports.find = find;\n exports.findIndex = findIndex;\n exports.findIndexWhere = findIndexWhere;\n exports.findLast = findLast;\n exports.findLastIndex = findLastIndex;\n exports.findLastIndexWhere = findLastIndexWhere;\n exports.findLastWhere = findLastWhere;\n exports.findWhere = findWhere;\n exports.flatMap = flatMap;\n exports.flatMapWith = flatMapWith;\n exports.flatten = flatten;\n exports.flip = flip;\n exports.forEach = forEach;\n exports.fromPairs = fromPairs;\n exports.generate = generate;\n exports.generic = generic;\n exports.getArgAt = getArgAt;\n exports.getAt = getAt;\n exports.getIn = getIn;\n exports.getIndex = getIndex;\n exports.getKey = getKey;\n exports.getPath = getPath;\n exports.getPathIn = getPathIn;\n exports.group = group;\n exports.groupBy = groupBy;\n exports.gt = gt;\n exports.gte = gte;\n exports.has = has;\n exports.hasKey = hasKey;\n exports.hasKeyValue = hasKeyValue;\n exports.hasOwn = hasOwn;\n exports.hasOwnKey = hasOwnKey;\n exports.hasPathValue = hasPathValue;\n exports.head = head;\n exports.identity = identity;\n exports.index = index;\n exports.indexBy = indexBy;\n exports.init = init;\n exports.insert = insert;\n exports.insertAt = insertAt;\n exports.intersection = intersection;\n exports.invoker = invoker;\n exports.invokerOn = invokerOn;\n exports.is = is;\n exports.isFinite = isFinite_;\n exports.isGT = isGT;\n exports.isGTE = isGTE;\n exports.isIn = isIn;\n exports.isInstanceOf = isInstanceOf;\n exports.isInteger = isInteger;\n exports.isLT = isLT;\n exports.isLTE = isLTE;\n exports.isNil = isNil;\n exports.isNull = isNull;\n exports.isSVZ = isSVZ;\n exports.isSafeInteger = isSafeInteger;\n exports.isType = isType;\n exports.isUndefined = isUndefined;\n exports.join = join;\n exports.joinWith = joinWith;\n exports.keySatisfies = keySatisfies;\n exports.keys = keys;\n exports.last = last;\n exports.list = list;\n exports.lt = lt;\n exports.lte = lte;\n exports.make = make;\n exports.map = map;\n exports.mapArgs = mapArgs;\n exports.mapValues = mapValues;\n exports.mapValuesWith = mapValuesWith;\n exports.mapWith = mapWith;\n exports.merge = merge;\n exports.mergeOwn = mergeOwn;\n exports.modulo = modulo;\n exports.multiply = multiply;\n exports.multiplyBy = multiplyBy;\n exports.not = not;\n exports.ownPairs = ownPairs;\n exports.ownValues = ownValues;\n exports.padLeft = padLeft;\n exports.padRight = padRight;\n exports.pairs = pairs;\n exports.partial = partial;\n exports.partialRight = partialRight;\n exports.partition = partition;\n exports.partitionWith = partitionWith;\n exports.pathExists = pathExists;\n exports.pathExistsIn = pathExistsIn;\n exports.pathSatisfies = pathSatisfies;\n exports.pick = pick;\n exports.pickIf = pickIf;\n exports.pickKeys = pickKeys;\n exports.pipe = pipe;\n exports.pluck = pluck;\n exports.pluckKey = pluckKey;\n exports.pull = pull;\n exports.pullFrom = pullFrom;\n exports.randomInt = randomInt;\n exports.range = range;\n exports.reduce = reduce;\n exports.reduceRight = reduceRight;\n exports.reduceRightWith = reduceRightWith;\n exports.reduceWith = reduceWith;\n exports.remainder = remainder;\n exports.rename = rename;\n exports.renameKeys = renameKeys;\n exports.renameWith = renameWith;\n exports.repeat = repeat;\n exports.reverse = reverse;\n exports.rotate = rotate;\n exports.rotateBy = rotateBy;\n exports.setAt = setAt;\n exports.setIn = setIn;\n exports.setIndex = setIndex;\n exports.setKey = setKey;\n exports.setPath = setPath;\n exports.setPathIn = setPathIn;\n exports.shallowFlatten = shallowFlatten;\n exports.skip = skip;\n exports.skipIf = skipIf;\n exports.skipKeys = skipKeys;\n exports.slice = slice;\n exports.sliceAt = sliceAt;\n exports.some = some;\n exports.someIn = someIn;\n exports.sort = sort;\n exports.sortWith = sortWith;\n exports.sortedInsert = sortedInsert;\n exports.sorter = sorter;\n exports.sorterDesc = sorterDesc;\n exports.subtract = subtract;\n exports.sum = sum;\n exports.tail = tail;\n exports.take = take;\n exports.takeFrom = takeFrom;\n exports.takeLastWhile = takeLastWhile;\n exports.takeWhile = takeWhile;\n exports.tapArgs = tapArgs;\n exports.tear = tear;\n exports.tearOwn = tearOwn;\n exports.testWith = testWith;\n exports.throttle = throttle;\n exports.transpose = transpose;\n exports.type = type;\n exports.unary = unary;\n exports.union = union;\n exports.unionBy = unionBy;\n exports.uniques = uniques;\n exports.uniquesBy = uniquesBy;\n exports.unless = unless;\n exports.updateAt = updateAt;\n exports.updateIn = updateIn;\n exports.updateIndex = updateIndex;\n exports.updateKey = updateKey;\n exports.updatePath = updatePath;\n exports.updatePathIn = updatePathIn;\n exports.validate = validate;\n exports.validateWith = validateWith;\n exports.values = values;\n exports.when = when;\n exports.zip = zip;\n exports.zipWithIndex = zipWithIndex;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n}));\n"]} \ No newline at end of file +{"version":3,"sources":["lamb.js"],"names":["global","factory","exports","module","define","amd","self","lamb","this","__","areSVZ","a","b","binary","fn","call","clamp","n","min","max","NaN","partial","args","Array","isArray","apply","arguments","boundArg","lastIdx","newArgs","argsLen","length","i","len","_makePartial3","shouldAritize","clampWithin","identity","value","compose","MAX_ARRAY_LENGTH","MAX_SAFE_INTEGER","_toArrayLength","forEach","arrayLike","iteratee","generic","Function","bind","isNull","isUndefined","isNil","_curry2","isRightCurry","isSVZ","map","result","mapWith","_makeReducer","step","accumulator","initialValue","nCalls","idx","TypeError","reduce","reduceWith","_toInteger","Math","floor","abs","slice","start","end","begin","upTo","resultLen","sliceAt","objectProtoToString","Object","prototype","toString","type","appendTo","concat","append","isIn","contains","_groupWith","makeValue","element","key","count","countBy","filter","predicate","push","not","uniquesBy","seen","uniques","dropFrom","drop","_takeOrDropWhile","isTake","fromLast","idxFrom","idxTo","lastHitIndex","increment","_getLastHitIndex","dropLastWhile","dropWhile","_makeArrayChecker","defaultResult","everyIn","every","filterWith","_findIndex","findIndex","find","findIndexWhere","findLastIndex","findLast","findLastIndexWhere","findLastWhere","findWhere","flatMap","array","el","arr","v","rLen","flatMapWith","_makeArrayFlattener","isDeep","_flatten","output","j","vLen","flatten","_toNaturalIndex","getIndex","index","getAt","group","groupBy","head","indexBy","init","insert","splice","insertAt","join","separator","String","joinWith","last","list","partition","partitionWith","getIn","obj","getKey","pluckKey","pullFrom","values","pull","reduceRight","reduceRightWith","rotate","amount","shift","rotateBy","_setIndex","updater","setAt","aritize","arity","setIndex","shallowFlatten","someIn","some","_compareWith","criteria","criterion","compare","isDescending","_comparer","_sorter","reader","comparer","_makeCriterion","_makeCriteria","sorters","sort","sorter","sorterDesc","sortWith","tail","takeFrom","take","takeLastWhile","takeWhile","transpose","minLen","elementLen","_makeTypeErrorFor","desiredType","toLowerCase","pipe","functions","unionBy","union","updateIndex","zipWithIndex","application","applyTo","_curry","isAutoCurry","_currier","argsHolder","holderLen","newArgsLen","reverse","c","_curry3","_invoker","methodName","boundArgs","target","method","boundArgsLen","finalArgsLen","finalArgs","ofs","_checkPredicates","checkAll","predicates","allOf","anyOf","areSame","gt","gte","is","isGT","isGTE","lt","isLT","lte","isLTE","sum","add","subtract","deduct","divide","divideBy","isInteger","multiply","multiplyBy","_forceToNumber","_isOwnEnumerable","propertyIsEnumerable","_safeEnumerables","_isEnumerable","indexOf","_getPathKey","includeNonEnumerables","_getPathInfo","parts","walkNonEnumerables","isValid","_toPathParts","path","split","getPathIn","_unsafeKeyListFrom","getKeys","enumerables","getPath","has","hasKey","hasOwn","hasOwnProperty","hasOwnKey","keys","make","names","valuesLen","mapValues","source","mapValuesWith","_merge","merge","mergeOwn","_keyToPairIn","_pairsFrom","ownPairs","_valuesFrom","ownValues","pairs","pathExistsIn","pathExists","pick","whitelist","pickIf","pickKeys","rename","keysMap","oldKeys","prop","renameKeys","_setIn","setIn","setKey","_setPathIn","partsLen","targetKey","_isArrayIndex","setPathIn","skip","blacklist","props","skipIf","skipKeys","_tearFrom","tear","tearOwn","updateIn","updateKey","updatePathIn","pathInfo","validate","checkers","errors","_checker","validateWith","_repeat","times","_getPadding","char","ceil","_search","search","adapter","always","asPartial","_asPartial","case","checker","message","keyPaths","pathSeparator","getValues","collect","condition","trueFn","falseFn","curry","curryRight","curryable","curryableRight","debounce","timespan","timeoutID","debounced","clearTimeout","setTimeout","difference","other","isNotInOther","flip","fromPairs","pairsList","pair","generate","limit","getArgAt","hasKeyValue","hasPathValue","intersection","lenA","invoker","invokerOn","isFinite","isInstanceOf","constructor","isSafeInteger","isType","typeName","keySatisfies","mapArgs","mapper","modulo","padLeft","padRight","partialRight","pathSatisfies","pluck","randomInt","random","range","remainder","renameWith","repeat","setPath","sortedInsert","_getInsertionIndex","pivot","tapArgs","tappers","tappersLen","testWith","pattern","s","throttle","lastCall","now","Date","unary","unless","updateAt","updatePath","when","zip","defineProperty"],"mappings":"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","file":"lamb.min.js","sourcesContent":["/**\n* @overview lamb - A lightweight, and docile, JavaScript library to help embracing functional programming.\n* @author Andrea Scartabelli \n* @version 0.58.0\n* @module lamb\n* @license MIT\n*/\n(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (global = global || self, factory(global.lamb = {}));\n}(this, function (exports) { 'use strict';\n\n /**\n * The placeholder object used in partial application.\n * @memberof module:lamb\n * @alias module:lamb.__\n * @category Special properties\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.57.0\n * @type {Object}\n */\n var __ = {};\n\n /**\n * Builds a function that returns a constant value.\n * It's actually the simplest form of the K combinator or Kestrel.\n * @example\n * var truth = _.always(true);\n *\n * truth() // => true\n * truth(false) // => true\n * truth(1, 2) // => true\n *\n * // the value being returned is actually the\n * // very same value passed to the function\n * var foo = {bar: \"baz\"};\n * var alwaysFoo = _.always(foo);\n *\n * alwaysFoo() === foo // => true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n function always (value) {\n return function () {\n return value;\n };\n }\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValueZero\" comparison.
\n * With this comparison NaN is equal to itself, but 0 and -0 are\n * considered the same value.
\n * See also {@link module:lamb.isSVZ|isSVZ} for a curried version building a predicate and\n * {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is} to perform a \"SameValue\" comparison.\n * @example\n * var testObject = {};\n *\n * _.areSVZ({}, testObject) // => false\n * _.areSVZ(testObject, testObject) // => true\n * _.areSVZ(\"foo\", \"foo\") // => true\n * _.areSVZ(0, -0) // => true\n * _.areSVZ(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.isSVZ|isSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSVZ (a, b) {\n return a !== a ? b !== b : a === b; // eslint-disable-line no-self-compare\n }\n\n /**\n * Builds a function that passes only two arguments to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * _.list(1, 2, 3, 4, 5) // => [1, 2, 3, 4, 5]\n * _.binary(_.list)(1, 2, 3, 4, 5) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.unary|unary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function binary (fn) {\n return function (a, b) {\n return fn.call(this, a, b);\n };\n }\n\n /**\n * \"Clamps\" a number within the given limits, both included.
\n * The function will convert to number all its parameters before starting any\n * evaluation, and will return NaN if min is greater\n * than max.\n * @example\n * _.clamp(-5, 0, 10) // => 0\n * _.clamp(5, 0, 10) // => 5\n * _.clamp(15, 0, 10) // => 10\n * _.clamp(0, 0, 10) // => 0\n * _.clamp(10, 0, 10) // => 10\n * _.is(_.clamp(-0, 0, 10), -0) // => true\n * _.clamp(10, 20, 15) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.clampWithin|clampWithin}\n * @since 0.13.0\n * @param {Number} n\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function clamp (n, min, max) {\n n = +n;\n min = +min;\n max = +max;\n\n if (min > max) {\n return NaN;\n } else {\n return n < min ? min : n > max ? max : n;\n }\n }\n\n /**\n * Builds a partially applied function.
\n * The {@link module:lamb.__|__} object can be used as a placeholder for arguments.
\n * @example\n * var __ = _.__;\n * var users = [\n * {id: 1, name: \"John\", active: true, confirmedMail: true},\n * {id: 2, name: \"Jane\", active: true, confirmedMail: false},\n * {id: 3, name: \"Mario\", active: false, confirmedMail: false}\n * ];\n * var isKeyTrue = _.partial(_.hasKeyValue, [__, true]);\n * var isActive = isKeyTrue(\"active\");\n * var hasConfirmedMail = isKeyTrue(\"confirmedMail\");\n *\n * _.map(users, isActive) // => [true, true, false]\n * _.map(users, hasConfirmedMail) // => [true, false, false]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.1.0\n * @param {Function} fn\n * @param {Array} args\n * @returns {Function}\n */\n function partial (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = 0;\n var newArgs = [];\n var argsLen = args.length;\n\n for (var i = 0, boundArg; i < argsLen; i++) {\n boundArg = args[i];\n newArgs[i] = boundArg === __ ? arguments[lastIdx++] : boundArg;\n }\n\n for (var len = arguments.length; lastIdx < len; lastIdx++) {\n newArgs[i++] = arguments[lastIdx];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a partial application of a ternary function so that its first parameter\n * is expected as the last one.
\n * The shouldAritize parameter is for the \"reduce\" functions, where\n * the absence of the initialValue transforms a \"fold\" operation into a\n * \"reduce\" one.\n * @private\n * @param {Function} fn\n * @param {Boolean} shouldAritize\n * @returns {Function}\n */\n function _makePartial3 (fn, shouldAritize) {\n return function (a, b) {\n var f = shouldAritize && arguments.length !== 2 ? binary(fn) : fn;\n\n return partial(f, [__, a, b]);\n };\n }\n\n /**\n * A curried version of {@link module:lamb.clamp|clamp}, expecting a min\n * and a max value, that builds a function waiting for the number to clamp.\n * @example\n * _.clampWithin(0, 10)(-5) // => 0\n * _.clampWithin(0, 10)(5) // => 5\n * _.clampWithin(0, 10)(15) // => 10\n * _.clampWithin(0, 10)(0) // => 0\n * _.clampWithin(0, 10)(10) // => 10\n * _.is(_.clampWithin(0, 10)(-0), -0) // => true\n * _.clampWithin(20, 15)(10) // => NaN\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.clamp|clamp}\n * @since 0.47.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Function}\n */\n var clampWithin = _makePartial3(clamp);\n\n /**\n * The I combinator. Any value passed to the function is simply returned as it is.\n * @example\n * var foo = {bar: \"baz\"};\n *\n * _.identity(foo) === foo // true\n *\n * @memberof module:lamb\n * @category Function\n * @see [SKI combinator calculus]{@link https://en.wikipedia.org/wiki/SKI_combinator_calculus}\n * @since 0.1.0\n * @param {*} value\n * @returns {*} The value passed as parameter.\n */\n function identity (value) {\n return value;\n }\n\n /**\n * Returns a function that is the composition of the functions given as parameters.\n * The first function consumes the result of the function that follows.\n * @example\n * var sayHi = function (name) { return \"Hi, \" + name; };\n * var capitalize = function (s) {\n * return s[0].toUpperCase() + s.substr(1).toLowerCase();\n * };\n * var fixNameAndSayHi = _.compose(sayHi, capitalize);\n *\n * sayHi(\"bOb\") // => \"Hi, bOb\"\n * fixNameAndSayHi(\"bOb\") // \"Hi, Bob\"\n *\n * var users = [{name: \"fred\"}, {name: \"bOb\"}];\n * var sayHiToUser = _.compose(fixNameAndSayHi, _.getKey(\"name\"));\n *\n * _.map(users, sayHiToUser) // [\"Hi, Fred\", \"Hi, Bob\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.pipe|pipe}\n * @since 0.1.0\n * @param {Function} a\n * @param {Function} b\n * @returns {Function}\n */\n function compose (a, b) {\n return arguments.length ? function () {\n return a.call(this, b.apply(this, arguments));\n } : identity;\n }\n\n var MAX_ARRAY_LENGTH = 4294967295;\n var MAX_SAFE_INTEGER = 9007199254740991;\n\n /**\n * Converts a value to a valid array length, thus an integer within\n * 0 and 232 - 1 (both included).\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toArrayLength (value) {\n return clamp(value, 0, MAX_ARRAY_LENGTH) >>> 0;\n }\n\n /* eslint-disable jsdoc/require-returns-check */\n\n /**\n * Executes the provided iteratee for each element of the given array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example Adding a CSS class to all elements of a NodeList in a browser environment:\n * var addClass = _.curry(function (className, element) {\n * element.classList.add(className);\n * });\n * var paragraphs = document.querySelectorAll(\"#some-container p\");\n *\n * _.forEach(paragraphs, addClass(\"main\"));\n * // each \"p\" element in the container will have the \"main\" class now\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Undefined}\n */\n function forEach (arrayLike, iteratee) {\n for (var i = 0, len = _toArrayLength(arrayLike.length); i < len; i++) {\n iteratee(arrayLike[i], i, arrayLike);\n }\n }\n\n /**\n * Creates generic functions out of methods.\n * @author A very little change on a great idea by [Irakli Gozalishvili]{@link https://github.com/Gozala/}.\n * Thanks for this *beautiful* one-liner (never liked your \"unbind\" naming choice, though).\n * @memberof module:lamb\n * @category Function\n * @function\n * @example\n * var join = _.generic(Array.prototype.join);\n *\n * join([1, 2, 3, 4, 5], \"-\") // => \"1-2-3-4-5\"\n *\n * // the function will work with any array-like object\n * join(\"hello\", \"-\") // => \"h-e-l-l-o\"\n *\n * @since 0.1.0\n * @param {Function} method\n * @returns {Function}\n */\n var generic = Function.bind.bind(Function.call);\n\n /**\n * Verifies if a value is null.\n * @example\n * _.isNull(null) // => true\n * _.isNull(void 0) // => false\n * _.isNull(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for undefined too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNull (value) {\n return value === null;\n }\n\n /**\n * Verifies if a value is undefined.\n * @example\n * _.isUndefined(null) // => false\n * _.isUndefined(void 0) // => true\n * _.isUndefined(false) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNil|isNil} if you want to check for null too.\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isUndefined (value) {\n return value === void 0;\n }\n\n /**\n * Verifies if a value is null or undefined.\n * @example\n * _.isNil(NaN) // => false\n * _.isNil({}) // => false\n * _.isNil(null) // => true\n * _.isNil(void 0) // => true\n * _.isNil() // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isNull|isNull}\n * @see {@link module:lamb.isUndefined|isUndefined}\n * @since 0.1.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isNil (value) {\n return isNull(value) || isUndefined(value);\n }\n\n /**\n * Curries a function of arity 2.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry2 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return isRightCurry ? fn.call(this, b, a) : fn.call(this, a, b);\n };\n };\n }\n\n /**\n * A curried version of {@link module:lamb.areSVZ|areSVZ}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValueZero\"\n * comparison.
\n * See also {@link module:lamb.areSame|areSame} and {@link module:lamb.is|is}\n * to perform a \"SameValue\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.isSVZ(john);\n * var isZero = _.isSVZ(0);\n * var isReallyNaN = _.isSVZ(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isZero(0) // => true\n * isZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSVZ|areSVZ}\n * @see {@link module:lamb.areSame|areSame}, {@link module:lamb.is|is}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var isSVZ = _curry2(areSVZ);\n\n /**\n * Builds a new array by applying the iteratee function to each element of the\n * received array-like object.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.map([\"Joe\", \"Mario\", \"Jane\"], _.invoker(\"toUpperCase\")) // => [\"JOE\", \"MARIO\", \"JANE\"]\n *\n * _.map([4, 9, 16], Math.sqrt); // => [2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.mapWith|mapWith}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function map (arrayLike, iteratee) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = iteratee(arrayLike[i], i, arrayLike);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.map|map} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var square = function (n) { return n * n; };\n * var getSquares = _.mapWith(square);\n *\n * getSquares([1, 2, 3, 4, 5]) // => [1, 4, 9, 16, 25]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.map|map}\n * @see {@link module:lamb.flatMap|flatMap}, {@link module:lamb.flatMapWith|flatMapWith}\n * @since 0.1.0\n * @param {ListIteratorCallback} iteratee\n * @returns {function}\n */\n var mapWith = _curry2(map, true);\n\n /**\n * Like {@link module:lamb.partial|partial} will build a partially applied function and\n * it will accept placeholders.
\n * The difference is that the bound arguments will be appended to the ones received by\n * the resulting function.\n * @example\n * Explaining the difference with partial:\n * var f1 = _.partial(_.list, [\"a\", \"b\", \"c\"]);\n * var f2 = _.partialRight(_.list, [\"a\", \"b\", \"c\"]);\n *\n * f1(\"d\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"d\", \"e\") // => [\"d\", \"e\", \"a\", \"b\", \"c\"]\n *\n * @example\n * Explaining placeholder substitutions:\n * var __ = _.__;\n * var f1 = _.partial(_.list, [\"a\", __, __, \"d\"]);\n * var f2 = _.partialRight(_.list, [\"a\", __, __, \"d\"]);\n *\n * f1(\"b\", \"c\", \"e\") // => [\"a\", \"b\", \"c\", \"d\", \"e\"]\n * f2(\"b\", \"c\", \"e\") // => [\"b\", \"a\", \"c\", \"e\", \"d\"]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}\n * @see {@link module:lamb.asPartial|asPartial}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @param {Function} fn\n * @param {Array} args\n * @since 0.52.0\n * @returns {Function}\n */\n function partialRight (fn, args) {\n return function () {\n if (!Array.isArray(args)) {\n return fn.apply(this, arguments);\n }\n\n var lastIdx = arguments.length - 1;\n var argsLen = args.length;\n var boundArgs = Array(argsLen);\n var newArgs = [];\n\n for (var i = argsLen - 1, boundArg; i > -1; i--) {\n boundArg = args[i];\n boundArgs[i] = boundArg === __ ? arguments[lastIdx--] : boundArg;\n }\n\n for (i = 0; i <= lastIdx; i++) {\n newArgs[i] = arguments[i];\n }\n\n for (var j = 0; j < argsLen; j++) {\n newArgs[i++] = boundArgs[j];\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Builds a reduce function. The step parameter must be 1\n * to build {@link module:lamb.reduce|reduce} and -1 to build\n * {@link module:lamb.reduceRight|reduceRight}.\n * @private\n * @param {Number} step\n * @returns {Function}\n */\n function _makeReducer (step) {\n return function (arrayLike, accumulator, initialValue) {\n var len = _toArrayLength(arrayLike.length);\n var idx = step === 1 ? 0 : len - 1;\n var nCalls;\n var result;\n\n if (arguments.length === 3) {\n nCalls = len;\n result = initialValue;\n } else {\n if (len === 0) {\n throw new TypeError(\"Reduce of empty array-like with no initial value\");\n }\n\n result = arrayLike[idx];\n idx += step;\n nCalls = len - 1;\n }\n\n for (; nCalls--; idx += step) {\n result = accumulator(result, arrayLike[idx], idx, arrayLike);\n }\n\n return result;\n };\n }\n\n /**\n * Reduces (or folds) the values of an array-like object, starting from the first, to a new\n * value using the provided accumulator function.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * _.reduce([1, 2, 3, 4], _.sum) // => 10\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRight|reduceRight}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduce = _makeReducer(1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduce} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceWith(_.sum)(arr) // => 15\n * _.reduceWith(_.subtract)(arr) // => -13\n * _.reduceWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceRightWith|reduceRightWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceWith = _makePartial3(reduce, true);\n\n /**\n * Converts a value to an integer.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _toInteger (value) {\n var n = +value;\n\n if (n !== n) { // eslint-disable-line no-self-compare\n return 0;\n } else if (n % 1 === 0) {\n return n;\n } else {\n return Math.floor(Math.abs(n)) * (n < 0 ? -1 : 1);\n }\n }\n\n /**\n * Builds an array by extracting a portion of an array-like object.
\n * Note that unlike the native array method this function ensures that dense\n * arrays are returned.
\n * Also, unlike the native method, the start and end\n * parameters aren't optional and will be simply converted to integer.
\n * See {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.slice(arr, 0, 2) // => [1, 2]\n * _.slice(arr, 2, -1) // => [3, 4]\n * _.slice(arr, -3, 5) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sliceAt|sliceAt}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike - Any array like object.\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Array}\n */\n function slice (arrayLike, start, end) {\n var len = _toArrayLength(arrayLike.length);\n var begin = _toInteger(start);\n var upTo = _toInteger(end);\n\n if (begin < 0) {\n begin = begin < -len ? 0 : begin + len;\n }\n\n if (upTo < 0) {\n upTo = upTo < -len ? 0 : upTo + len;\n } else if (upTo > len) {\n upTo = len;\n }\n\n var resultLen = upTo - begin;\n var result = resultLen > 0 ? Array(resultLen) : [];\n\n for (var i = 0; i < resultLen; i++) {\n result[i] = arrayLike[begin + i];\n }\n\n return result;\n }\n\n /**\n * Given the start and end bounds, builds a partial application\n * of {@link module:lamb.slice|slice} expecting the array-like object to slice.
\n * See also {@link module:lamb.dropFrom|dropFrom} and {@link module:lamb.drop|drop} if you want a\n * slice to the end of the array-like.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var s = \"hello\";\n * var dropFirstAndLast = _.sliceAt(1, -1);\n *\n * dropFirstAndLast(arr) // => [2, 3, 4]\n * dropFirstAndLast(s) // => [\"e\", \"l\", \"l\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.slice|slice}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.48.0\n * @param {Number} start - Index at which to begin extraction.\n * @param {Number} end - Index at which to end extraction. Extracts up to but not including end.\n * @returns {Function}\n */\n var sliceAt = _makePartial3(slice);\n\n var objectProtoToString = Object.prototype.toString;\n\n /**\n * Retrieves the \"type tag\" from the given value.\n * @example\n * var x = 5;\n * var y = new Number(5);\n *\n * typeof x // => \"number\"\n * typeof y // => \"object\"\n * _.type(x) // => \"Number\"\n * _.type(y) // => \"Number\"\n *\n * _.type(Object.prototype.toString) // => \"Function\"\n * _.type(/a/) // => \"RegExp\"\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.9.0\n * @param {*} value\n * @returns {String}\n */\n function type (value) {\n return objectProtoToString.call(value).slice(8, -1);\n }\n\n /**\n * Appends the given value at the end of a copy of the provided array-like object.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.appendTo(arr, 5) // => [1, 2, 3, 4, 5]\n * _.appendTo(arr, [5]) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.append|append}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Array}\n */\n function appendTo (arrayLike, value) {\n return slice(arrayLike, 0, arrayLike.length).concat([value]);\n }\n\n /**\n * A curried version of {@link module:lamb.appendTo|appendTo} that uses the value to append\n * to build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4];\n *\n * _.append(5)(arr) // => [1, 2, 3, 4, 5]\n * _.append([5])(arr) // => [1, 2, 3, 4, [5]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.appendTo|appendTo}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt}\n * @since 0.44.0\n * @param {*} value\n * @returns {Function}\n */\n var append = _curry2(appendTo, true);\n\n /**\n * Checks if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.contains|contains} for a curried version building a predicate.\n * @example\n * var numbers = [0, 1, 2, 3, NaN];\n *\n * _.isIn(numbers, 1) // => true\n * _.isIn(numbers, 0) // => true\n * _.isIn(numbers, -0) // => true\n * _.isIn(numbers, NaN) // => true\n * _.isIn(numbers, 5) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.contains|contains}\n * @since 0.13.0\n * @param {ArrayLike} arrayLike\n * @param {*} value\n * @returns {Boolean}\n */\n function isIn (arrayLike, value) {\n var result = false;\n\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (areSVZ(value, arrayLike[i])) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Builds a predicate to check if an array-like object contains the given value.
\n * Please note that the equality test is made with {@link module:lamb.areSVZ|areSVZ}; so you can\n * check for NaN, but 0 and -0 are the same value.
\n * See also {@link module:lamb.isIn|isIn} for an uncurried version.\n * @example\n * var containsNaN = _.contains(NaN);\n *\n * containsNaN([0, 1, 2, 3, NaN]) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.isIn|isIn}\n * @since 0.13.0\n * @param {*} value\n * @returns {Function}\n */\n var contains = _curry2(isIn, true);\n\n /**\n * Builds a \"grouping function\" for an array-like object.\n * @private\n * @param {Function} makeValue\n * @returns {Function}\n */\n function _groupWith (makeValue) {\n return function (arrayLike, iteratee) {\n var result = {};\n var len = arrayLike.length;\n\n for (var i = 0, element, key; i < len; i++) {\n element = arrayLike[i];\n key = iteratee(element, i, arrayLike);\n result[key] = makeValue(result[key], element);\n }\n\n return result;\n };\n }\n\n /**\n * Transforms an array-like object in a lookup table with the keys generated by the provided\n * iteratee, having as values the count of matches for the key.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 17},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n * var getAgeStatus = function (person) { return person.age >= 18 ? \"adult\" : \"minor\"; };\n *\n * _.count(persons, getAgeStatus) // => {\"adult\": 1, \"minor\": 3}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var count = _groupWith(function (a) {\n return a ? ++a : 1;\n });\n\n /**\n * A curried version of {@link module:lamb.count|count} that uses the provided iteratee to\n * build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCityOrUnknown = _.adapter([_.getKey(\"city\"), _.always(\"Unknown\")]);\n * var countByCity = _.countBy(getCityOrUnknown);\n *\n * countByCity(persons) // => {\"New York\": 2, \"Rome\": 1, \"Unknown\": 1}\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.count|count}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var countBy = _curry2(count, true);\n\n /**\n * Builds an array comprised of all values of the array-like object passing the predicate\n * test.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n *\n * _.filter([\"Foo\", \"bar\", \"baZ\"], isLowerCase) // => [\"bar\"]\n *\n * // the function will work with any array-like object\n * _.filter(\"fooBAR\", isLowerCase) // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.filterWith|filterWith}\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @since 0.1.0\n * @returns {Array}\n */\n function filter (arrayLike, predicate) {\n var len = arrayLike.length;\n var result = [];\n\n for (var i = 0; i < len; i++) {\n predicate(arrayLike[i], i, arrayLike) && result.push(arrayLike[i]);\n }\n\n return result;\n }\n\n /**\n * Returns a predicate that negates the given one.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isOdd = _.not(isEven);\n *\n * isOdd(5) // => true\n * isOdd(4) // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @since 0.1.0\n * @param {Function} predicate\n * @returns {Function}\n */\n function not (predicate) {\n return function () {\n return !predicate.apply(this, arguments);\n };\n }\n\n /**\n * Using the provided iteratee, builds a function that will return an array comprised of the\n * unique elements of an array-like object. The values being compared are the ones returned by\n * the iteratee.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniques|uniques} if you don't need to transform your values before the\n * comparison.\n * @example\n * var data = [\n * {id: \"1\", name: \"John\"},\n * {id: \"4\", name: \"Jane\"},\n * {id: \"5\", name: \"Joe\"},\n * {id: \"1\", name: \"Mario\"},\n * {id: \"5\", name: \"Paolo\"},\n * ];\n * var uniquesById = _.uniquesBy(_.getKey(\"id\"));\n *\n * uniquesById(data) // => [{id: \"1\", name: \"John\"}, {id: \"4\", name: \"Jane\"}, {id: \"5\", name: \"Joe\"}]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.uniques|uniques}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function uniquesBy (iteratee) {\n return function (arrayLike) {\n var result = [];\n\n for (var i = 0, len = arrayLike.length, seen = [], value; i < len; i++) {\n value = iteratee(arrayLike[i], i, arrayLike);\n\n if (!isIn(seen, value)) {\n seen.push(value);\n result.push(arrayLike[i]);\n }\n }\n\n return result;\n };\n }\n\n /**\n * Returns an array comprised of the unique elements of the given array-like object.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.uniquesBy|uniquesBy} if you need to transform your values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.uniques([-0, 1, 2, 0, 2, 3, 4, 3, 5, 1]) // => [-0, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.uniquesBy|uniquesBy}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var uniques = uniquesBy(identity);\n\n /**\n * Returns an array of unique items present only in the first of the two given\n * array-like objects. To determine uniqueness the function uses the\n * [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 1, 3, 4];\n * var a2 = [2, 4, 5, 6];\n * var a3 = [3, 4, 5, 2, 1];\n *\n * _.difference(a1, a2) // => [1, 3]\n * _.difference(a2, a3) // => [6]\n * _.difference(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.intersection|intersection}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.pull|pull}, {@link module:lamb.pullFrom|pullFrom}\n * @since 0.6.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} other\n * @returns {Array}\n */\n function difference (arrayLike, other) {\n var isNotInOther = partial(not(isIn), [other]);\n\n return uniques(filter(arrayLike, isNotInOther));\n }\n\n /**\n * Builds an array without the first n elements of the given array or array-like object.\n * Note that, being this only a shortcut for a specific use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.dropFrom(arr, 2) // => [3, 4, 5]\n * _.dropFrom(arr, -1) // => [5]\n * _.dropFrom(arr, -10) // => [1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function dropFrom (arrayLike, n) {\n return slice(arrayLike, n, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.dropFrom|dropFrom} that expects the number of elements\n * to drop to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.dropFrom|dropFrom} about passing a\n * negative n.\n * @example\n * var drop2 = _.drop(2);\n *\n * drop2([1, 2, 3, 4, 5]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.5.0\n * @see {@link module:lamb.dropFrom|dropFrom}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @param {Number} n\n * @returns {Function}\n */\n var drop = _curry2(dropFrom, true);\n\n /**\n * Gets the index of the last element satisfying a predicate in an array-like object.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\n function _getLastHitIndex (arrayLike, predicate, fromLast) {\n var idx;\n var increment;\n var len = arrayLike.length;\n\n if (fromLast) {\n idx = len - 1;\n increment = -1;\n } else {\n idx = 0;\n increment = 1;\n }\n\n while (idx >= 0 && idx < len && predicate(arrayLike[idx], idx, arrayLike)) {\n idx += increment;\n }\n\n return idx;\n }\n\n /**\n * Helper to build the {@link module:lamb.takeWhile|takeWhile},\n * {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropWhile|dropWhile} and\n * {@link module:lamb.dropLastWhile|dropLastWhile} functions.\n * @private\n * @param {Boolean} isTake\n * @param {Boolean} fromLast\n * @returns {Function}\n */\n function _takeOrDropWhile (isTake, fromLast) {\n return function (predicate) {\n return function (arrayLike) {\n var idxFrom;\n var idxTo;\n var lastHitIndex = _getLastHitIndex(arrayLike, predicate, fromLast);\n\n if (isTake && fromLast) {\n idxFrom = lastHitIndex + 1;\n idxTo = arrayLike.length;\n } else if (isTake) {\n idxFrom = 0;\n idxTo = lastHitIndex;\n } else if (!isTake && fromLast) {\n idxFrom = 0;\n idxTo = lastHitIndex + 1;\n } else {\n idxFrom = lastHitIndex;\n idxTo = arrayLike.length;\n }\n\n return slice(arrayLike, idxFrom, idxTo);\n };\n };\n }\n\n /**\n * Builds a function that drops the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropLastWhileIsEven = _.dropLastWhile(isEven);\n *\n * dropLastWhileIsEven([2, 4, 6, 8]) // => []\n * dropLastWhileIsEven([2, 4, 7, 8]) // => [2, 4, 7]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var dropLastWhile = _takeOrDropWhile(false, true);\n\n /**\n * Builds a function that drops the first elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var dropWhileIsEven = _.dropWhile(isEven);\n *\n * dropWhileIsEven([2, 4, 6, 8]) // => []\n * dropWhileIsEven([2, 4, 7, 8]) // => [7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeWhile|takeWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var dropWhile = _takeOrDropWhile(false, false);\n\n /**\n * Helper to build the {@link module:lamb.everyIn|everyIn} or the\n * {@link module:lamb.someIn|someIn} function.\n * @private\n * @param {Boolean} defaultResult\n * @returns {Function}\n */\n function _makeArrayChecker (defaultResult) {\n return function (arrayLike, predicate) {\n for (var i = 0, len = arrayLike.length; i < len; i++) {\n if (defaultResult ^ !!predicate(arrayLike[i], i, arrayLike)) {\n return !defaultResult;\n }\n }\n\n return defaultResult;\n };\n }\n\n /**\n * Checks if all the elements in an array-like object satisfy the given predicate.
\n * The function will stop calling the predicate as soon as it returns a falsy value.
\n * Note that an empty array-like will always produce a true result regardless of the\n * predicate because of [vacuous truth]{@link https://en.wikipedia.org/wiki/Vacuous_truth}.
\n * Also note that unlike the native\n * [Array.prototype.every]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: true},\n * {\"name\": \"John\", \"age\": 40, active: true},\n * {\"name\": \"Mario\", \"age\": 17, active: true},\n * {\"name\": \"Paolo\", \"age\": 15, active: true}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.everyIn(persons, isAdult) // => false\n * _.everyIn(persons, isActive) // => true\n *\n * @example Showing the difference with Array.prototype.every:\n * var isDefined = _.not(_.isUndefined);\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.every(isDefined) // => true\n * _.everyIn(arr, isDefined) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.every|every}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var everyIn = _makeArrayChecker(true);\n\n /**\n * A curried version of {@link module:lamb.everyIn|everyIn} that expects a predicate\n * to build a function waiting for the array-like to act upon.\n * @example\n * var data = [2, 3, 5, 6, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var allEvens = _.every(isEven);\n * var allIntegers = _.every(_.isInteger);\n *\n * allEvens(data) // => false\n * allIntegers(data) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.everyIn|everyIn}\n * @see {@link module:lamb.some|some}, {@link module:lamb.someIn|someIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var every = _curry2(everyIn, true);\n\n /**\n * A curried version of {@link module:lamb.filter|filter} that uses the given predicate\n * to build a function expecting the array-like object to act upon.\n * @example\n * var isLowerCase = function (s) { return s.toLowerCase() === s; };\n * var getLowerCaseEntries = _.filterWith(isLowerCase);\n *\n * getLowerCaseEntries([\"Foo\", \"bar\", \"baZ\"]) // => [\"bar\"]\n *\n * // array-like objects can be used as well\n * getLowerCaseEntries(\"fooBAR\") // => [\"f\", \"o\", \"o\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.filter|filter}\n * @since 0.9.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var filterWith = _curry2(filter, true);\n\n /**\n * Helper to create the {@link module:lamb.findIndex|findIndex} and\n * {@link module:lamb.findLastIndex|findLastIndex} functions.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @param {Boolean} fromLast\n * @returns {Number}\n */\n function _findIndex (arrayLike, predicate, fromLast) {\n var start;\n var increment;\n var len = arrayLike.length;\n var result = -1;\n\n if (fromLast) {\n start = len - 1;\n increment = -1;\n } else {\n start = 0;\n increment = 1;\n }\n\n for (var i = start; i < len && i >= 0; i += increment) {\n if (predicate(arrayLike[i], i, arrayLike)) {\n result = i;\n break;\n }\n }\n\n return result;\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns its\n * index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findIndex(persons, _.hasKeyValue(\"age\", 40)) // => 1\n * _.findIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, false);\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object and returns it if\n * the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.find(persons, _.hasKeyValue(\"age\", 40)) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.find(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function find (arrayLike, predicate) {\n var idx = findIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * A curried version of {@link module:lamb.findIndex|findIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEvenIdx = _.findIndexWhere(isEven);\n *\n * findEvenIdx([1, 3, 4, 5, 6, 7]) // => 2\n * findEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findIndex|findIndex}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findIndexWhere = _curry2(findIndex, true);\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object starting from\n * the end and returns its index if the search is successful. Returns -1 otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 40)) // => 3\n * _.findLastIndex(persons, _.hasKeyValue(\"age\", 41)) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Number}\n */\n function findLastIndex (arrayLike, predicate) {\n return _findIndex(arrayLike, predicate, true);\n }\n\n /**\n * Searches for an element satisfying the predicate in the given array-like object starting from the end\n * and returns it if the search is successful. Returns undefined otherwise.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 40}\n * ];\n *\n * _.findLast(persons, _.hasKeyValue(\"surname\", \"Doe\")) // => {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40}\n * _.findLast(persons, _.hasKeyValue(\"age\", 41)) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {*}\n */\n function findLast (arrayLike, predicate) {\n var idx = findLastIndex(arrayLike, predicate);\n\n return idx === -1 ? void 0 : arrayLike[idx];\n }\n\n /**\n * A curried version of {@link module:lamb.findLastIndex|findLastIndex} that uses the given predicate\n * to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findLastEvenIdx = _.findLastIndexWhere(isEven);\n *\n * findLastEvenIdx([1, 3, 4, 5, 6, 7]) // => 4\n * findLastEvenIdx([1, 3, 5, 7]) // => -1\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastIndex|findLastIndex}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findLastIndexWhere = _curry2(findLastIndex, true);\n\n /**\n * A curried version of {@link module:lamb.findLast|findLast} that uses the given\n * predicate to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findLastWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 6, 7]) // => 6\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @see {@link module:lamb.find|find}, {@link module:lamb.findWhere|findWhere}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findLastWhere = _curry2(findLast, true);\n\n /**\n * A curried version of {@link module:lamb.find|find} that uses the given\n * predicate to build a function expecting the array-like object to search.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var findEven = _.findWhere(isEven);\n *\n * findEven([1, 3, 4, 5, 7]) // => 4\n * findEven([1, 3, 5, 7]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.find|find}\n * @see {@link module:lamb.findIndex|findIndex}, {@link module:lamb.findIndexWhere|findIndexWhere}\n * @see {@link module:lamb.findLast|findLast}, {@link module:lamb.findLastWhere|findLastWhere}\n * @see {@link module:lamb.findLastIndex|findLastIndex},\n * {@link module:lamb.findLastIndexWhere|findLastIndexWhere}\n * @since 0.41.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var findWhere = _curry2(find, true);\n\n /**\n * Similar to {@link module:lamb.map|map}, but if the mapping function returns an array this will\n * be concatenated, rather than pushed, to the final result.\n * @example Showing the difference with map:\n * var words = [\"foo\", \"bar\"];\n * var toCharArray = function (s) { return s.split(\"\"); };\n *\n * _.map(words, toCharArray) // => [[\"f\", \"o\", \"o\"], [\"b\", \"a\", \"r\"]]\n * _.flatMap(words, toCharArray) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.flatMapWith|flatMapWith}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.1.0\n * @param {Array} array\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function flatMap (array, iteratee) {\n return reduce(array, function (result, el, idx, arr) {\n var v = iteratee(el, idx, arr);\n\n if (!Array.isArray(v)) {\n v = [v];\n }\n\n for (var i = 0, len = v.length, rLen = result.length; i < len; i++) {\n result[rLen + i] = v[i];\n }\n\n return result;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.flatMap|flatMap} that uses provided iteratee\n * to build a function expecting the array to act upon.\n * @example\n * var toCharArray = function (s) { return s.split(\"\"); };\n * var wordsToCharArray = _.flatMapWith(toCharArray);\n *\n * wordsToCharArray([\"foo\", \"bar\"]) // => [\"f\", \"o\", \"o\", \"b\", \"a\", \"r\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatMap|flatMap}\n * @see {@link module:lamb.map|map}, {@link module:lamb.mapWith|mapWith}\n * @since 0.11.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var flatMapWith = _curry2(flatMap, true);\n\n /**\n * Flattens an array.\n * @private\n * @param {Array} array - The source array\n * @param {Boolean} isDeep - Whether to perform a deep flattening or not\n * @param {Array} output - An array to collect the result\n * @param {Number} idx - The next index to be filled in the output\n * @returns {Array} The output array filled with the results\n */\n function _flatten (array, isDeep, output, idx) {\n for (var i = 0, len = array.length, value, j, vLen; i < len; i++) {\n value = array[i];\n\n if (!Array.isArray(value)) {\n output[idx++] = value;\n } else if (isDeep) {\n _flatten(value, true, output, idx);\n idx = output.length;\n } else {\n vLen = value.length;\n output.length += vLen;\n\n for (j = 0; j < vLen; j++) {\n output[idx++] = value[j];\n }\n }\n }\n\n return output;\n }\n\n /**\n * Helper to build the {@link module:lamb.flatten|flatten} and\n * {@link module:lamb.shallowFlatten|shallowFlatten} functions.\n * @private\n * @function\n * @param {Boolean} isDeep\n * @returns {Function}\n */\n var _makeArrayFlattener = _curry2(function (isDeep, array) {\n return Array.isArray(array) ? _flatten(array, isDeep, [], 0) : slice(array, 0, array.length);\n });\n\n /**\n * Flattens an array.\n * @example Showing the difference with shallowFlatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.shallowFlatten|shallowFlatten}\n * @since 0.1.0\n * @param {Array} array\n * @returns {Array}\n */\n var flatten = _makeArrayFlattener(true);\n\n /**\n * Checks if the given number, even negative, represents an array-like index\n * within the provided length. If so returns its natural number equivalent.
\n * Returns NaN otherwise.\n * @private\n * @param {Number} idx\n * @param {Number} len\n * @returns {Number}\n */\n function _toNaturalIndex (idx, len) {\n idx = _toInteger(idx);\n\n return idx >= -len && idx < len ? idx < 0 ? idx + len : idx : NaN;\n }\n\n /**\n * Retrieves the element at the given index in an array-like object.
\n * Like {@link module:lamb.slice|slice} the index can be negative.
\n * If the index isn't supplied, or if its value isn't an integer within the array-like bounds,\n * the function will return undefined.
\n * getIndex will throw an exception when receives null or\n * undefined in place of an array-like object, but returns undefined\n * for any other value.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.getIndex(arr, 1) // => 2\n * _.getIndex(arr, -1) // => 5\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.getAt|getAt}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @returns {*}\n */\n function getIndex (arrayLike, index) {\n var idx = _toNaturalIndex(index, _toArrayLength(arrayLike.length));\n\n return idx === idx ? arrayLike[idx] : void 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * A curried version of {@link module:lamb.getIndex|getIndex} that uses the provided index\n * to build a function expecting the array-like object holding the element we want to retrieve.\n * @example\n * var getFifthElement = _.getAt(4);\n *\n * getFifthElement([1, 2, 3, 4, 5]) // => 5\n * getFifthElement(\"foo bar\") // => \"b\"\n * getFifthElement([]) // => undefined\n * getFifthElement(\"foo\") // => undefined\n *\n * @example Using negative indexes:\n * _.getAt(-2)([1, 2, 3]) // => 2\n * _.getAt(-3)(\"foo\") // => \"f\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.16.0\n * @see {@link module:lamb.getIndex|getIndex}\n * @see {@link module:lamb.head|head} and {@link module:lamb.last|last} for common use cases shortcuts.\n * @param {Number} index\n * @returns {Function}\n */\n var getAt = _curry2(getIndex, true);\n\n /**\n * Transforms an array-like object into a lookup table using the provided iteratee as a grouping\n * criterion to generate keys and values.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"city\": \"New York\"},\n * {\"name\": \"John\", \"city\": \"New York\"},\n * {\"name\": \"Mario\", \"city\": \"Rome\"},\n * {\"name\": \"Paolo\"}\n * ];\n * var getCity = _.getKey(\"city\");\n * var personsByCity = _.group(persons, getCity);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"undefined\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @example Adding a custom value for missing keys:\n *\n * var getCityOrUnknown = _.adapter([getCity, _.always(\"Unknown\")]);\n *\n * var personsByCity = _.group(persons, getCityOrUnknown);\n *\n * // \"personsByCity\" holds:\n * // {\n * // \"New York\": [\n * // {\"name\": \"Jane\", \"city\": \"New York\"},\n * // {\"name\": \"John\", \"city\": \"New York\"}\n * // ],\n * // \"Rome\": [\n * // {\"name\": \"Mario\", \"city\": \"Rome\"}\n * // ],\n * // \"Unknown\": [\n * // {\"name\": \"Paolo\"}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.groupBy|groupBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var group = _groupWith(function (a, b) {\n if (!a) {\n return [b];\n }\n\n a[a.length] = b;\n\n return a;\n });\n\n /**\n * A curried version of {@link module:lamb.group|group} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12},\n * {\"name\": \"John\", \"age\": 40},\n * {\"name\": \"Mario\", \"age\": 18},\n * {\"name\": \"Paolo\", \"age\": 15}\n * ];\n *\n * var getAgeStatus = function (person) { return person.age > 20 ? \"over 20\" : \"under 20\"; };\n * var groupByAgeStatus = _.groupBy(getAgeStatus);\n *\n * var personsByAgeStatus = groupByAgeStatus(persons);\n *\n * // \"personsByAgeStatus\" holds:\n * // {\n * // \"under 20\": [\n * // {\"name\": \"Jane\", \"age\": 12},\n * // {\"name\": \"Mario\", \"age\": 18},\n * // {\"name\": \"Paolo\", \"age\": 15}\n * // ],\n * // \"over 20\": [\n * // {\"name\": \"John\", \"age\": 40}\n * // ]\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.group|group}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.index|index}, {@link module:lamb.indexBy|indexBy}\n * @since 0.7.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var groupBy = _curry2(group, true);\n\n /**\n * Retrieves the first element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.head([1, 2, 3]) // => 1\n * _.head(\"hello\") // => \"h\"\n * _.head([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.last|last}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var head = getAt(0);\n\n /**\n * Similar to {@link module:lamb.group|group}, but the generated lookup table will have\n * only one element of the original array-like object for each value.
\n * Should be used only when you're sure that your iteratee won't produce\n * duplicate keys, otherwise only the last evaluated element will be in the result.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"id\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"},\n * // \"4\": {id: 4, name: \"John\"}\n * // }\n *\n * @example Result of an iteratee producing a duplicate key:\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"},\n * {id: 4, name: \"John\"}\n * ];\n *\n * var indexedUsers = _.index(users, _.getKey(\"name\"));\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"John\": {\"id\": 4, \"name\": \"John\"},\n * // \"Jane\": {\"id\": 2, \"name\": \"Jane\"},\n * // \"Mario\": {\"id\": 3, \"name\": \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.indexBy|indexBy}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} iteratee\n * @returns {Object}\n */\n var index = _groupWith(function (a, b) {\n return b;\n });\n\n /**\n * A curried version of {@link module:lamb.index|index} that uses the provided iteratee\n * to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {id: 1, name: \"John\"},\n * {id: 2, name: \"Jane\"},\n * {id: 3, name: \"Mario\"}\n * ];\n * var indexByID = _.indexBy(_.getKey(\"id\"));\n *\n * var indexedUsers = indexByID(users);\n *\n * // \"indexedUsers\" holds:\n * // {\n * // \"1\": {id: 1, name: \"John\"},\n * // \"2\": {id: 2, name: \"Jane\"},\n * // \"3\": {id: 3, name: \"Mario\"}\n * // }\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.index|index}\n * @see {@link module:lamb.count|count}, {@link module:lamb.countBy|countBy}\n * @see {@link module:lamb.group|group}, {@link module:lamb.groupBy|groupBy}\n * @since 0.21.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n var indexBy = _curry2(index, true);\n\n /**\n * Returns a copy of the given array-like object without the last element.\n * @example\n * _.init([1, 2, 3, 4]) // => [1, 2, 3]\n * _.init([1]) // => []\n * _.init([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.tail|tail}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var init = partial(slice, [__, 0, -1]);\n\n /**\n * Inserts the provided element in a copy of an array-like object at the\n * specified index.
\n * If the index is greater than the length of the array-like, the element\n * will be appended at the end.
\n * Negative indexes are allowed; when a negative index is out of bounds\n * the element will be inserted at the start of the resulting array.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insert(arr, 3, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, -2, 99) // => [1, 2, 3, 99, 4, 5]\n * _.insert(arr, 10, 99) // => [1, 2, 3, 4, 5, 99]\n * _.insert(arr, -10, 99) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.insertAt|insertAt}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} element\n * @returns {Array}\n */\n function insert (arrayLike, index, element) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n result.splice(index, 0, element);\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.insert|insert}\n * expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.insertAt(3, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(-2, 99)(arr) // => [1, 2, 3, 99, 4, 5]\n * _.insertAt(10, 99)(arr) // => [1, 2, 3, 4, 5, 99]\n * _.insertAt(-10, 99)(arr) // => [99, 1, 2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.insert|insert}\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.append|append}, {@link module:lamb.appendTo|appendTo}\n * @since 0.27.0\n * @param {Number} index\n * @param {*} element\n * @returns {Function}\n */\n var insertAt = _makePartial3(insert);\n\n /**\n * Returns an array of every unique item that is included in all two given arrays\n * or array-like objects.
\n * Note that this function uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var a1 = [1, 2, 3, 4];\n * var a2 = [2, 5, 4, 2, 6];\n * var a3 = [5, 6, 7];\n *\n * _.intersection(a1, a2) // => [2, 4]\n * _.intersection(a2, a3) // => [5, 6]\n * _.intersection(a1, a3) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.union|union}, {@link module:lamb.unionBy|unionBy}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function intersection (a, b) {\n var result = [];\n var lenA = a.length;\n\n if (lenA && b.length) {\n for (var i = 0; i < lenA; i++) {\n !isIn(result, a[i]) && isIn(b, a[i]) && result.push(a[i]);\n }\n }\n\n return result;\n }\n\n /**\n * Transforms an array-like object into a string by joining its elements with\n * the given separator.
\n * Note that unlike the native method, this function won't convert\n * null and undefined values in the array to empty\n * strings and that the separator parameter isn't optional.
\n * See the examples about these differences.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n *\n * _.join(words, \"-\") // => \"foo-bar-baz\"\n *\n * @example Showing the differences with the native array method:\n * var mixed = [1, null, 2, undefined, 3, NaN, 4, 5];\n * var numbers = [1, 2, 3];\n *\n * _.join(mixed, \"-\") // => \"1-null-2-undefined-3-NaN-4-5\"\n * mixed.join(\"-\") // => \"1--2--3-NaN-4-5\"\n *\n * _.join(numbers) // => \"1undefined2undefined3\"\n * numbers.join() // => \"1,2,3\"\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.joinWith|joinWith}\n * @since 0.58.0\n * @param {ArrayLike} arrayLike\n * @param {String} separator\n * @returns {String}\n */\n function join (arrayLike, separator) {\n return map(arrayLike, String).join(String(separator));\n }\n\n /**\n * A curried version of {@link module:lamb.join|join} that accepts an optional\n * separator and builds a function expecting the array-like object to act upon.
\n * Please refer to the description and examples of {@link module:lamb.join|join}\n * to understand the differences with the native array method.\n * @example\n * var words = [\"foo\", \"bar\", \"baz\"];\n * var joinWithDash = _.joinWith(\"-\");\n *\n * joinWithDash(words) // => \"foo-bar-baz\"\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.join|join}\n * @since 0.58.0\n * @param {String} separator\n * @returns {Function}\n */\n var joinWith = _curry2(join, true);\n\n /**\n * Retrieves the last element of an array-like object.
\n * Just a common use case of {@link module:lamb.getAt|getAt} exposed for convenience.\n * @example\n * _.last([1, 2, 3]) // => 3\n * _.last(\"hello\") // => \"o\"\n * _.last([]) // => undefined\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.head|head}\n * @see {@link module:lamb.getIndex|getIndex}, {@link module:lamb.getAt|getAt}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {*}\n */\n var last = getAt(-1);\n\n /**\n * Builds helper functions to extract portions of the arguments\n * object rather efficiently without having to write for loops\n * manually for each case.
\n * The arguments object needs to be passed to the apply method\n * of the generated function.\n * @private\n * @param {Number} idx\n * @returns {Function}\n */\n function _argsToArrayFrom (idx) {\n return function () {\n var argsLen = arguments.length || idx;\n var len = argsLen - idx;\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = arguments[i + idx];\n }\n\n return result;\n };\n }\n\n /**\n * Generates an array with the values passed as arguments.
\n * Behaves like ES6's [Array.of]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of}.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @since 0.1.0\n * @param {...*} value\n * @returns {Array}\n */\n var list = _argsToArrayFrom(0);\n\n /**\n * Splits an array-like object in two lists: the first with the elements satisfying the given predicate,\n * the others with the remaining elements.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n *\n * _.partition(numbers, isEven) // => [[2, 4, 6, 8, 10], [1, 3, 5, 7, 9]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.partitionWith|partitionWith}\n * @since 0.11.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Array}\n */\n function partition (arrayLike, predicate) {\n var result = [[], []];\n var len = arrayLike.length;\n\n for (var i = 0, el; i < len; i++) {\n el = arrayLike[i];\n result[predicate(el, i, arrayLike) ? 0 : 1].push(el);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.partition|partition} that uses the provided\n * predicate to build a function expecting the array-like object to act upon.\n * @example\n * var users = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * ];\n * var isActive = _.hasKeyValue(\"active\", true);\n * var splitByActiveStatus = _.partitionWith(isActive);\n *\n * splitByActiveStatus(users) // =>\n * // [[\n * // {\"name\": \"John\", \"surname\": \"Doe\", \"active\": true},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\", \"active\": true}\n * // ], [\n * // {\"name\": \"Jane\", \"surname\": \"Doe\", \"active\": false},\n * // {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"active\": false}\n * // ]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.partition|partition}\n * @since 0.11.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var partitionWith = _curry2(partition, true);\n\n /**\n * Returns the value of the object property with the given key.\n * @example\n * var user = {name: \"John\"};\n *\n * _.getIn(user, \"name\") // => \"John\";\n * _.getIn(user, \"surname\") // => undefined\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getKey|getKey}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.18.0\n * @param {Object} obj\n * @param {String} key\n * @returns {*}\n */\n function getIn (obj, key) {\n return obj[key];\n }\n\n /**\n * A curried version of {@link module:lamb.getIn|getIn}.
\n * Receives a property name and builds a function expecting the object from which we want to retrieve\n * the property.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {name: \"jane\"};\n * var getName = _.getKey(\"name\");\n *\n * getName(user1) // => \"john\"\n * getName(user2) // => \"jane\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getIn|getIn}\n * @see {@link module:lamb.getPath|getPath}, {@link module:lamb.getPathIn|getPathIn}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var getKey = _curry2(getIn, true);\n\n /**\n * \"Plucks\" the values of the specified key from a list of objects.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n *\n * _.pluck(persons, \"age\") // => [12, 40, 18, 15]\n *\n * var lists = [\n * [1, 2],\n * [3, 4, 5],\n * [6]\n * ];\n *\n * _.pluck(lists, \"length\") // => [2, 3, 1]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pluckKey|pluckKey}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {String} key\n * @returns {Array}\n */\n function pluck (arrayLike, key) {\n return map(arrayLike, getKey(key));\n }\n\n /**\n * A curried version of {@link module:lamb.pluck|pluck} expecting the key to retrieve to\n * build a function waiting for the array-like object to act upon.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"surname\": \"Doe\", \"age\": 12},\n * {\"name\": \"John\", \"surname\": \"Doe\", \"age\": 40},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\", \"age\": 18},\n * {\"name\": \"Paolo\", \"surname\": \"Bianchi\", \"age\": 15}\n * ];\n * var getAges = _.pluckKey(\"age\");\n *\n * getAges(persons) // => [12, 40, 18, 15]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pluck|pluck}\n * @since 0.12.0\n * @param {String} key\n * @returns {Function}\n */\n var pluckKey = compose(mapWith, getKey);\n\n /**\n * Creates an array copy of the given array-like object without the\n * specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.pullFrom(arr, [2, 5]) // => [1, 3, 4]\n *\n * @example It's not the same as {@link module:lamb.difference|difference}:\n *\n * var arr = [1,1,2,3,4,4,5];\n *\n * _.pullFrom(arr, [1, 2]) // => [3, 4, 4, 5]\n * _.difference(arr, [1, 2]) // => [3, 4, 5]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.pull|pull}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} arrayLike\n * @param {ArrayLike} values\n * @returns {Array}\n */\n function pullFrom (arrayLike, values) {\n return values ? filter(arrayLike, function (element) {\n return !isIn(values, element);\n }) : slice(arrayLike, 0, arrayLike.length);\n }\n\n /**\n * A curried version of {@link module:lamb.pullFrom|pullFrom} expecting\n * a list of values to build a function waiting for an array-like object.
\n * The new function will create an array copy of the array-like without\n * the specified values.
\n * The equality test is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * See examples in {@link module:lamb.pullFrom|pullFrom} about the\n * relationship with {@link module:lamb.difference|difference}.\n * @example\n * var scores = [40, 20, 30, 10];\n * var newScores = [30, 10];\n * var pullNewScores = _.pull(newScores);\n *\n * pullNewScores(scores) // => [40, 20]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.pullFrom|pullFrom}\n * @see {@link module:lamb.difference|difference}\n * @since 0.45.0\n * @param {ArrayLike} values\n * @returns {Function}\n */\n var pull = _curry2(pullFrom, true);\n\n /**\n * Same as {@link module:lamb.reduce|reduce}, but starts the fold operation from the last\n * element instead.
\n * Note that unlike the native array method this function doesn't skip unassigned or deleted indexes.\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduce|reduce}\n * @see {@link module:lamb.reduceWith|reduceWith}, {@link module:lamb.reduceRightWith|reduceRightWith}\n * @since 0.1.0\n * @param {ArrayLike} arrayLike\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {*}\n */\n var reduceRight = _makeReducer(-1);\n\n /**\n * A partial application of {@link module:lamb.reduce|reduceRight} that uses the\n * provided accumulator and the optional initialValue to\n * build a function expecting the array-like object to act upon.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.reduceRightWith(_.sum)(arr) // => 15\n * _.reduceRightWith(_.subtract)(arr) // => -5\n * _.reduceRightWith(_.subtract, 0)(arr) // => -15\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.reduceWith|reduceWith}\n * @see {@link module:lamb.reduce|reduce}, {@link module:lamb.reduce|reduceRight}\n * @since 0.27.0\n * @param {AccumulatorCallback} accumulator\n * @param {*} [initialValue]\n * @returns {Function}\n */\n var reduceRightWith = _makePartial3(reduceRight, true);\n\n /**\n * Reverses a copy of the given array-like object.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.reverse(arr) // => [3, 2, 1];\n *\n * // `arr` still is [1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @since 0.19.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function reverse (arrayLike) {\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0, ofs = len - 1; i < len; i++) {\n result[i] = arrayLike[ofs - i];\n }\n\n return result;\n }\n\n /**\n * Returns a copy of the given array-like with the element rotated by the desired amount.\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.rotate(arr, 3) // => [3, 4, 5, 1, 2]\n * _.rotate(arr, -3) // => [4, 5, 1, 2, 3]\n * _.rotate(arr, 11) // => [5, 1, 2, 3, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.rotateBy|rotateBy}\n * @since 0.55.0\n * @param {ArrayLike} arrayLike\n * @param {Number} amount\n * @returns {Array}\n */\n function rotate (arrayLike, amount) {\n var len = arrayLike.length;\n var shift = amount % len;\n\n return slice(arrayLike, -shift, len).concat(slice(arrayLike, 0, -shift));\n }\n\n /**\n * A curried version of {@link module:lamb.rotate|rotate}.
\n * Uses the given amount to build a function expecting the array to rotate by that amount.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n * var rotateByTwo = _.rotateBy(2);\n *\n * rotateByTwo(arr) // => [4, 5, 1, 2, 3]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.rotate|rotate}\n * @since 0.55.0\n * @param {Number} amount\n * @returns {Function}\n */\n var rotateBy = _curry2(rotate, true);\n\n /**\n * Sets an index in an array-like object.
\n * If provided with an updater function it will use it to update the current value,\n * otherwise sets the index to the specified value.\n * @private\n * @param {ArrayLike} arrayLike\n * @param {Number} idx\n * @param {*} [value]\n * @param {Function} [updater]\n * @returns {Array}\n */\n function _setIndex (arrayLike, idx, value, updater) {\n var result = slice(arrayLike, 0, arrayLike.length);\n var n = _toNaturalIndex(idx, result.length);\n\n if (n === n) { // eslint-disable-line no-self-compare\n result[n] = arguments.length === 4 ? updater(arrayLike[n]) : value;\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.setIndex|setIndex} that builds\n * a function that creates a copy of an array-like object with the given\n * index changed to the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.setAt(2, 99)(arr) // => [1, 2, 99, 4, 5]\n * arr // => [1, 2, 3, 4, 5]\n *\n * _.setAt(10, 99)(arr) // => [1, 2, 3, 4, 5] (not a reference to `arr`)\n *\n * @example Using negative indexes:\n * _.setAt(-1, 99)(arr) // => [1, 2, 3, 4, 99]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setIndex|setIndex}\n * @since 0.17.0\n * @param {Number} index\n * @param {*} value\n * @returns {Function}\n */\n var setAt = _makePartial3(_setIndex);\n\n /**\n * Builds a new function that passes only the specified amount of arguments to the original one.
\n * As {@link module:lamb.slice|slice} is used to extract the arguments, you can also\n * pass a negative arity.\n * @example\n * Math.max(10, 11, 45, 99) // => 99\n * _.aritize(Math.max, 2)(10, 11, 45, 99) // => 11\n *\n * @example Using a negative arity:\n * _.aritize(Math.max, -1)(10, 11, 45, 99) // => 45\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.binary|binary}, {@link module:lamb.unary|unary} for common use cases shortcuts\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} arity\n * @returns {Function}\n */\n function aritize (fn, arity) {\n return function () {\n var n = _toInteger(arity);\n var args = list.apply(null, arguments).slice(0, n);\n\n for (var i = args.length; i < n; i++) {\n args[i] = void 0;\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed to\n * the desired value.
\n * If the index is not an integer or if it's out of bounds, the function\n * will return a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [1, 2, 3];\n *\n * _.setIndex(arr, 1, 99) // => [1, 99, 3]\n * _.setIndex(arr, -1, 99) // => [1, 2, 99]\n * _.setIndex(arr, 10, 99) // => [1, 2, 3] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.setAt|setAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {*} value\n * @returns {Array}\n */\n var setIndex = aritize(_setIndex, 3);\n\n /**\n * Flattens the \"first level\" of an array.\n * @example Showing the difference with flatten:\n * var arr = [1, 2, [3, 4, [5, 6]], 7, 8];\n *\n * _.flatten(arr) // => [1, 2, 3, 4, 5, 6, 7, 8]\n * _.shallowFlatten(arr) // => [1, 2, 3, 4, [5, 6], 7, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.flatten|flatten}\n * @since 0.9.0\n * @param {Array} array\n * @returns {Array}\n */\n var shallowFlatten = _makeArrayFlattener(false);\n\n /**\n * Checks if at least one element in an array-like object satisfies the given predicate.
\n * The function will stop calling the predicate as soon as it returns a truthy value.
\n * Note that unlike the native\n * [Array.prototype.some]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some},\n * this function won't skip deleted or unassigned indexes.\n * @example\n * var persons = [\n * {\"name\": \"Jane\", \"age\": 12, active: false},\n * {\"name\": \"John\", \"age\": 40, active: false},\n * {\"name\": \"Mario\", \"age\": 17, active: false},\n * {\"name\": \"Paolo\", \"age\": 15, active: false}\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n * var isActive = _.hasKeyValue(\"active\", true);\n *\n * _.someIn(persons, isAdult) // => true\n * _.someIn(persons, isActive) // => false\n *\n * @example Showing the difference with Array.prototype.some:\n * var arr = new Array(5);\n * arr[3] = 99;\n *\n * arr.some(_.isUndefined) // => false\n * _.someIn(arr, _.isUndefined) // => true\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.some|some}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ArrayLike} arrayLike\n * @param {ListIteratorCallback} predicate\n * @returns {Boolean}\n */\n var someIn = _makeArrayChecker(false);\n\n /**\n * A curried version of {@link module:lamb.someIn|someIn} that uses the given predicate to\n * build a function waiting for the array-like to act upon.\n * @example\n * var data = [1, 3, 5, 6, 7, 8];\n * var isEven = function (n) { return n % 2 === 0; };\n * var containsEvens = _.some(isEven);\n * var containsStrings = _.some(_.isType(\"String\"));\n *\n * containsEvens(data) // => true\n * containsStrings(data) // => false\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.someIn|someIn}\n * @see {@link module:lamb.every|every}, {@link module:lamb.everyIn|everyIn}\n * @since 0.39.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var some = _curry2(someIn, true);\n\n /**\n * Accepts a list of sorting criteria with at least one element\n * and builds a function that compares two values with such criteria.\n * @private\n * @param {Sorter[]} criteria\n * @returns {Function}\n */\n function _compareWith (criteria) {\n return function (a, b) {\n var len = criteria.length;\n var criterion = criteria[0];\n var result = criterion.compare(a.value, b.value);\n\n for (var i = 1; result === 0 && i < len; i++) {\n criterion = criteria[i];\n result = criterion.compare(a.value, b.value);\n }\n\n if (result === 0) {\n result = a.index - b.index;\n }\n\n return criterion.isDescending ? -result : result;\n };\n }\n\n /**\n * The default comparer for sorting functions.
\n * If the given values are of different types they\n * will be both converted to strings.
\n * Uses the SameValueZero comparison.\n * @private\n * @param {*} a\n * @param {*} b\n * @returns {Number} -1 | 0 | 1\n */\n function _comparer (a, b) {\n var result = 0;\n\n if (typeof a !== typeof b) {\n a = String(a);\n b = String(b);\n }\n\n if (!areSVZ(a, b)) {\n // eslint-disable-next-line no-self-compare\n result = a > b || a !== a ? 1 : -1;\n }\n\n return result;\n }\n\n /**\n * Builds a sorting criterion. If the comparer function is missing, the default\n * comparer will be used instead.\n * @private\n * @param {Function} reader\n * @param {Boolean} isDescending\n * @param {Function} [comparer]\n * @returns {Sorter}\n */\n function _sorter (reader, isDescending, comparer) {\n if (typeof reader !== \"function\" || reader === identity) {\n reader = null;\n }\n\n if (typeof comparer !== \"function\") {\n comparer = _comparer;\n }\n\n return {\n isDescending: isDescending === true,\n compare: function (a, b) {\n if (reader) {\n a = reader(a);\n b = reader(b);\n }\n\n return comparer(a, b);\n }\n };\n }\n\n /**\n * Converts a sorting function to a sorting criterion if necessary.\n * @private\n * @param {Function} criterion\n * @returns {Sorter}\n */\n function _makeCriterion (criterion) {\n return criterion && typeof criterion.compare === \"function\" ? criterion : _sorter(criterion);\n }\n\n /**\n * Builds a list of sorting criteria from a list of sorter functions. Returns a list containing\n * a single default sorting criterion if the sorter list is empty.\n * @private\n * @param {Function[]} sorters\n * @returns {Sorter[]}\n */\n function _makeCriteria (sorters) {\n return sorters && sorters.length ? map(sorters, _makeCriterion) : [_sorter()];\n }\n\n /**\n * Returns a [stably]{@link https://en.wikipedia.org/wiki/Sorting_algorithm#Stability} sorted\n * copy of an array-like object using the given criteria.
\n * Sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function, but you\n * can also pass simple \"reader\" functions and default ascending sorters will be built for you.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used\n * in the comparison.
\n * Please note that if the arguments received by the default comparer aren't of the same type,\n * they will be compared as strings.\n *\n * @example Stable sort:\n * var persons = [\n * {\"name\": \"John\", \"surname\" :\"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"},\n * {\"name\": \"John\", \"surname\" :\"Moe\"},\n * {\"name\": \"Jane\", \"surname\": \"Foe\"}\n * ];\n *\n * var personsByName = _.sort(persons, [_.getKey(\"name\")]);\n *\n * // personsByName holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Stable multi-sort:\n * var personsByNameAscSurnameDesc = _.sort(persons, [\n * _.getKey(\"name\"),\n * _.sorterDesc(_.getKey(\"surname\"))\n * ]);\n *\n * // personsByNameAscSurnameDesc holds:\n * // [\n * // {\"name\": \"Jane\", \"surname\": \"Foe\"},\n * // {\"name\": \"John\", \"surname\" :\"Moe\"},\n * // {\"name\": \"John\", \"surname\" :\"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @example Using custom comparers:\n * var localeSorter = new Intl.Collator(\"it\");\n * var chars = [\"a\", \"è\", \"à\", \"é\", \"c\", \"b\", \"e\"];\n *\n * _.sort(chars, [localeSorter]) // => [\"a\", \"à\", \"b\", \"c\", \"e\", \"é\", \"è\"]\n *\n * var localeSorterDesc = _.sorterDesc(_.identity, localeSorter.compare);\n *\n * _.sort(chars, [localeSorterDesc]) // => [\"è\", \"é\", \"e\", \"c\", \"b\", \"à\", \"a\"]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {ArrayLike} arrayLike\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Array}\n */\n function sort (arrayLike, sorters) {\n var criteria = _makeCriteria(sorters);\n var len = _toArrayLength(arrayLike.length);\n var result = Array(len);\n\n for (var i = 0; i < len; i++) {\n result[i] = { value: arrayLike[i], index: i };\n }\n\n result.sort(_compareWith(criteria));\n\n for (i = 0; i < len; i++) {\n result[i] = result[i].value;\n }\n\n return result;\n }\n\n /**\n * Establishes at which index an element should be inserted in a sorted array to respect\n * the array order. Needs the comparer used to sort the array.\n * @private\n * @param {Array} array\n * @param {*} element\n * @param {Function} comparer\n * @param {Number} start\n * @param {Number} end\n * @returns {Number}\n */\n function _getInsertionIndex (array, element, comparer, start, end) {\n if (array.length === 0) {\n return 0;\n }\n\n var pivot = (start + end) >> 1;\n var result = comparer(\n { value: element, index: pivot },\n { value: array[pivot], index: pivot }\n );\n\n if (end - start <= 1) {\n return result < 0 ? pivot : pivot + 1;\n } else if (result < 0) {\n return _getInsertionIndex(array, element, comparer, start, pivot);\n } else if (result === 0) {\n return pivot + 1;\n } else {\n return _getInsertionIndex(array, element, comparer, pivot, end);\n }\n }\n\n /**\n * Inserts an element in a copy of a sorted array respecting the sort order.\n * @example With simple values:\n * _.sortedInsert([], 1) // => [1]\n * _.sortedInsert([2, 4, 6], 5) // => [2, 4, 5, 6]\n * _.sortedInsert([4, 2, 1], 3, _.sorterDesc()) // => [4, 3, 2, 1]\n *\n * @example With complex values:\n * var persons = [\n * {\"name\": \"jane\", \"surname\": \"doe\"},\n * {\"name\": \"John\", \"surname\": \"Doe\"},\n * {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * ];\n *\n * var getLowerCaseName = _.compose(\n * _.invoker(\"toLowerCase\"),\n * _.getKey(\"name\")\n * );\n *\n * var result = _.sortedInsert(\n * persons,\n * {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * getLowerCaseName\n * );\n *\n * // `result` holds:\n * // [\n * // {\"name\": \"jane\", \"surname\": \"doe\"},\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"marco\", \"surname\": \"Rossi\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @see {@link module:lamb.insert|insert}, {@link module:lamb.insertAt|insertAt} to insert the element\n * at a specific index\n * @since 0.27.0\n * @param {ArrayLike} arrayLike\n * @param {*} element\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]] - The sorting criteria\n * used to sort the array.\n * @returns {Array}\n */\n function sortedInsert (arrayLike, element, sorters) {\n var result = slice(arrayLike, 0, arrayLike.length);\n\n if (arguments.length === 1) {\n return result;\n }\n\n var criteria = _makeCriteria(sorters);\n var idx = _getInsertionIndex(result, element, _compareWith(criteria), 0, result.length);\n\n result.splice(idx, 0, element);\n\n return result;\n }\n\n /**\n * Creates an ascending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.1.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorter = partial(_sorter, [__, false, __]);\n\n /**\n * Creates a descending sort criterion with the provided reader and\n * comparer.
\n * See {@link module:lamb.sort|sort} for various examples.\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sortedInsert|sortedInsert}\n * @see {@link module:lamb.sort|sort}, {@link module:lamb.sortWith|sortWith}\n * @see {@link module:lamb.sorter|sorter}\n * @since 0.15.0\n * @param {Function} [reader={@link module:lamb.identity|identity}] A function meant to generate a\n * simple value from a complex one. The function should evaluate the array element and supply the\n * value to be passed to the comparer.\n * @param {Function} [comparer] An optional custom comparer function.\n * @returns {Sorter}\n */\n var sorterDesc = partial(_sorter, [__, true, __]);\n\n /**\n * Builds a partial application of {@link module:lamb.sort|sort} using the provided criteria.\n * The returned function expects the array-like object to sort.\n * As usual, sorting criteria are built using Lamb's {@link module:lamb.sorter|sorter} function,\n * but you can also pass simple \"reader\" functions and default ascending sorters will be built.
\n * A \"reader\" is a function that evaluates the array element and supplies the value to be used in\n * the comparison.
\n * See {@link module:lamb.sort|sort} for more examples.\n *\n * @example\n * var sortAsNumbers = _.sortWith([parseFloat]);\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * sortAsNumbers(weights) // => [\"1 Kg\", \"2 Kg\", \"7 Kg\", \"10 Kg\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.sort|sort}\n * @see {@link module:lamb.sorter|sorter}, {@link module:lamb.sorterDesc|sorterDesc}\n * @since 0.15.0\n * @param {Sorter[]|Function[]} [sorters=[{@link module:lamb.sorter|sorter()}]]\n * @returns {Function}\n */\n var sortWith = _curry2(sort, true);\n\n /**\n * Returns a copy of the given array-like object without the first element.\n * @example\n * _.tail([1, 2, 3, 4]) // => [2, 3, 4]\n * _.tail([1]) // => []\n * _.tail([]) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.init|init}\n * @see {@link module:lamb.head|head}, {@link module:lamb.last|last}\n * @since 0.16.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n var tail = drop(1);\n\n /**\n * Retrieves the first n elements from an array or array-like object.
\n * Note that, being this a shortcut for a common use case of {@link module:lamb.slice|slice},\n * n can be a negative number.\n * @example\n * var arr = [1, 2, 3, 4, 5];\n *\n * _.takeFrom(arr, 3) // => [1, 2, 3]\n * _.takeFrom(arr, -1) // => [1, 2, 3, 4]\n * _.takeFrom(arr, -10) // => []\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.51.0\n * @param {ArrayLike} arrayLike\n * @param {Number} n\n * @returns {Array}\n */\n function takeFrom (arrayLike, n) {\n return slice(arrayLike, 0, n);\n }\n\n /**\n * A curried version of {@link module:lamb.takeFrom|takeFrom} that expects the number of elements\n * to retrieve to build a function waiting for the list to take the elements from.
\n * See the note and examples for {@link module:lamb.takeFrom|takeFrom} about passing a\n * negative n.\n * @example\n * var take2 = _.take(2);\n *\n * take2([1, 2, 3, 4, 5]) // => [1, 2]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.takeFrom|takeFrom}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @since 0.5.0\n * @param {Number} n\n * @returns {Function}\n */\n var take = _curry2(takeFrom, true);\n\n /**\n * Builds a function that takes the last elements satisfying a predicate\n * from an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeLastWhileIsEven = _.takeLastWhile(isEven);\n *\n * takeLastWhileIsEven([1, 3, 5, 7]) // => []\n * takeLastWhileIsEven([2, 3, 6, 8]) // => [6, 8]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeWhile|takeWhile}, {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @since 0.58.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var takeLastWhile = _takeOrDropWhile(true, true);\n\n /**\n * Builds a function that takes the first elements satisfying a predicate from\n * an array or array-like object.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var takeWhileIsEven = _.takeWhile(isEven);\n *\n * takeWhileIsEven([1, 2, 4, 6, 8]) // => []\n * takeWhileIsEven([2, 4, 7, 8]) // => [2, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.dropWhile|dropWhile}\n * @see {@link module:lamb.takeLastWhile|takeLastWhile}, {@link module:lamb.dropLastWhile|dropLastWhile}\n * @see {@link module:lamb.takeFrom|takeFrom}, {@link module:lamb.take|take}\n * @see {@link module:lamb.dropFrom|dropFrom}, {@link module:lamb.drop|drop}\n * @since 0.5.0\n * @param {ListIteratorCallback} predicate\n * @returns {Function}\n */\n var takeWhile = _takeOrDropWhile(true, false);\n\n /**\n * Transposes a matrix. Can also be used to reverse a {@link module:lamb.zip|zip} operation.
\n * Just like {@link module:lamb.zip|zip}, the received array-like objects will be truncated to the\n * shortest length.\n * @example Transposing a matrix:\n * _.transpose([\n * [1, 2, 3],\n * [4, 5, 6],\n * [7, 8, 9]\n * ]) // =>\n * // [\n * // [1, 4, 7],\n * // [2, 5, 8],\n * // [3, 6, 9]\n * // ]\n *\n * @example Showing the relationship with zip:\n * var zipped = _.zip([\"a\", \"b\", \"c\"], [1, 2, 3]); // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.transpose(zipped) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array}\n */\n function transpose (arrayLike) {\n var minLen = MAX_ARRAY_LENGTH;\n var len = _toArrayLength(arrayLike.length);\n\n if (len === 0) {\n return [];\n }\n\n for (var j = 0, elementLen; j < len; j++) {\n elementLen = _toArrayLength(arrayLike[j].length);\n\n if (elementLen < minLen) {\n minLen = elementLen;\n }\n }\n\n var result = Array(minLen);\n\n for (var i = 0, el; i < minLen; i++) {\n el = result[i] = Array(len);\n\n for (j = 0; j < len; j++) {\n el[j] = arrayLike[j][i];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a TypeError stating that it's not possible to convert the given value to the\n * desired type.\n * @private\n * @param {*} value\n * @param {String} desiredType\n * @returns {TypeError}\n */\n function _makeTypeErrorFor (value, desiredType) {\n return new TypeError(\"Cannot convert \" + type(value).toLowerCase() + \" to \" + desiredType);\n }\n\n /**\n * Creates a pipeline of functions, where each function consumes the result of the previous one.\n * @example\n * var __ = _.__;\n * var square = _.partial(Math.pow, [__, 2]);\n * var getMaxAndSquare = _.pipe([Math.max, square]);\n *\n * getMaxAndSquare(3, 5) // => 25\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.compose|compose}\n * @since 0.1.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function pipe (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n var len = functions.length;\n\n return len ? function () {\n var result = functions[0].apply(this, arguments);\n\n for (var i = 1; i < len; i++) {\n result = functions[i].call(this, result);\n }\n\n return result;\n } : identity;\n }\n\n /**\n * Using the provided iteratee to transform values, builds a function that will\n * return an array of the unique elements in the two provided array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.union|union} if you don't need to compare transformed values.\n * @example\n * var unionByFloor = _.unionBy(Math.floor);\n *\n * unionByFloor([2.8, 3.2, 1.5], [3.5, 1.2, 4]) // => [2.8, 3.2, 1.5, 4]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.union|union}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.51.0\n * @param {ListIteratorCallback} iteratee\n * @returns {Function}\n */\n function unionBy (iteratee) {\n return pipe([binary(list), flatMapWith(drop(0)), uniquesBy(iteratee)]);\n }\n\n /**\n * Returns a list of every unique element present in the two given array-like objects.
\n * Uses the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}\n * to test the equality of values.
\n * When two values are considered equal, the first occurence will be the one included\n * in the result array.
\n * See also {@link module:lamb.unionBy|unionBy} if you need to transform the values before\n * the comparison or if you have to extract them from complex ones.\n * @example\n * _.union([1, 2, 3, 2], [2, 3, 4]) // => [1, 2, 3, 4]\n * _.union(\"abc\", \"bcd\") // => [\"a\", \"b\", \"c\", \"d\"]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.unionBy|unionBy}\n * @see {@link module:lamb.difference|difference}\n * @see {@link module:lamb.intersection|intersection}\n * @since 0.5.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n var union = unionBy(identity);\n\n /**\n * Builds a function that creates a copy of an array-like object with the given index\n * changed by applying the provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateAt(1, toUpperCase)(arr) // => [\"a\", \"B\", \"c\"]\n * _.updateAt(-1, toUpperCase)(arr) // => [\"a\", \"b\", \"C\"]\n * _.updateAt(10, toUpperCase)(arr) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.updateIndex|updateIndex}\n * @since 0.22.0\n * @param {Number} index\n * @param {Function} updater\n * @returns {Function}\n */\n function updateAt (index, updater) {\n return function (arrayLike) {\n return _setIndex(arrayLike, index, null, updater);\n };\n }\n\n /**\n * Creates a copy of an array-like object with the given index changed by applying the\n * provided function to its value.
\n * If the index is not an integer or if it's out of bounds, the function will return\n * a copy of the original array.
\n * Negative indexes are allowed.\n * @example\n * var arr = [\"a\", \"b\", \"c\"];\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIndex(arr, 1, toUpperCase) // => [\"a\", \"B\", \"c\"]\n * _.updateIndex(arr, -1, toUpperCase) // => [\"a\", \"b\", \"C\"]\n * _.updateIndex(arr, 10, toUpperCase) // => [\"a\", \"b\", \"c\"] (not a reference to `arr`)\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.updateAt|updateAt}\n * @since 0.23.0\n * @param {ArrayLike} arrayLike\n * @param {Number} index\n * @param {Function} updater\n * @returns {Array}\n */\n var updateIndex = partial(_setIndex, [__, __, null, __]);\n\n /**\n * Builds a list of arrays out of the two given array-like objects by pairing items with\n * the same index.
\n * The received array-like objects will be truncated to the shortest length.\n * @example\n * _.zip(\n * [\"a\", \"b\", \"c\"],\n * [1, 2, 3]\n * ) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * _.zip([1, 2, 3, 4], [5, 6, 7]) // => [[1, 5], [2, 6], [3, 7]]\n *\n * @memberof module:lamb\n * @category Array\n * @see {@link module:lamb.transpose|transpose} for the reverse operation\n * @see {@link module:lamb.zipWithIndex|zipWithIndex}\n * @since 0.14.0\n * @param {ArrayLike} a\n * @param {ArrayLike} b\n * @returns {Array}\n */\n function zip (a, b) {\n return transpose([a, b]);\n }\n\n /**\n * \"{@link module:lamb.zip|Zips}\" an array-like object by pairing its values with their index.\n * @example\n * _.zipWithIndex([\"a\", \"b\", \"c\"]) // => [[\"a\", 0], [\"b\", 1], [\"c\", 2]]\n *\n * @memberof module:lamb\n * @category Array\n * @function\n * @see {@link module:lamb.zip|zip}\n * @since 0.14.0\n * @param {ArrayLike} arrayLike\n * @returns {Array>}\n */\n var zipWithIndex = mapWith(binary(list));\n\n /**\n * Applies the given function to a list of arguments.\n * @example\n * _.application(_.sum, [3, 4]) // => 7\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.apply|apply}, {@link module:lamb.applyTo|applyTo}\n * @since 0.47.0\n * @param {Function} fn\n * @param {ArrayLike} args\n * @returns {*}\n */\n function application (fn, args) {\n return fn.apply(this, Object(args));\n }\n\n /**\n * A left-curried version of {@link module:lamb.application|application}. Expects the function\n * to apply and builds a function waiting for the arguments array.\n * @example\n * var arrayMax = _.apply(Math.max);\n *\n * arrayMax([4, 5, 2, 6, 1]) // => 6\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.applyTo|applyTo}\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n var apply = _curry2(application);\n\n /**\n * A right-curried version of {@link module:lamb.application|application}. Expects an array-like\n * object to use as arguments and builds a function waiting for the target of the application.\n * @example\n * var data = [3, 4];\n * var applyToData = _.applyTo(data);\n *\n * applyToData(_.sum) // => 7\n * applyToData(_.multiply) // => 12\n *\n * @memberof module:lamb\n * @category Function\n * @function\n * @see {@link module:lamb.application|application}, {@link module:lamb.apply|apply}\n * @since 0.47.0\n * @param {ArrayLike} args\n * @returns {Function}\n */\n var applyTo = _curry2(application, true);\n\n /**\n * Keeps building a partial application of the received function as long\n * as it's called with placeholders; applies the original function to\n * the collected parameters otherwise.
\n * The function checks only the public placeholder to gain a little performance\n * as no function in Lamb is built with {@link module:lamb.asPartial|asPartial}.\n * @private\n * @param {Function} fn\n * @param {Array} argsHolder\n * @returns {Function|*}\n */\n function _asPartial (fn, argsHolder) {\n return function () {\n var argsLen = arguments.length;\n var lastIdx = 0;\n var newArgs = [];\n\n for (var i = 0, len = argsHolder.length, boundArg; i < len; i++) {\n boundArg = argsHolder[i];\n newArgs[i] = boundArg === __ && lastIdx < argsLen ? arguments[lastIdx++] : boundArg;\n }\n\n while (lastIdx < argsLen) {\n newArgs[i++] = arguments[lastIdx++];\n }\n\n for (i = 0; i < argsLen; i++) {\n if (arguments[i] === __) {\n return _asPartial(fn, newArgs);\n }\n }\n\n for (i = 0, len = newArgs.length; i < len; i++) {\n if (newArgs[i] === __) {\n newArgs[i] = void 0;\n }\n }\n\n return fn.apply(this, newArgs);\n };\n }\n\n /**\n * Decorates the received function so that it can be called with\n * placeholders to build a partial application of it.
\n * The difference with {@link module:lamb.partial|partial} is that, as long as\n * you call the generated function with placeholders, another partial application\n * of the original function will be built.
\n * The final application will happen when one of the generated functions is\n * invoked without placeholders, using the parameters collected so far.
\n * This function comes in handy when you need to build different specialized\n * functions starting from a basic one, but it's also useful when dealing with\n * optional parameters as you can decide to apply the function even if its arity\n * hasn't been entirely consumed.\n * @example Explaining the function's behaviour:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + c;\n * });\n *\n * f(4, 3, 2) // => 9\n * f(4, __, 2)(3) // => 9\n * f(__, 3, __)(4, __)(2) // => 9\n *\n * @example Exploiting optional parameters:\n * var __ = _.__;\n * var f = _.asPartial(function (a, b, c) {\n * return a + b + (c || 0);\n * });\n *\n * var addFive = f(5, __);\n * addFive(2) // => 7\n *\n * var addNine = addFive(4, __);\n * addNine(11) // => 20\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.__|__} The placeholder object.\n * @since 0.36.0\n * @param {Function} fn\n * @returns {Function}\n */\n function asPartial (fn) {\n return _asPartial(fn, []);\n }\n\n /**\n * Accepts a series of functions and builds a new function. The functions in the series\n * will then be applied, in order, with the values received by the function built with\n * collect.
\n * The collected results will be returned in an array.\n * @example\n * var user = {\n * id: \"jdoe\",\n * name: \"John\",\n * surname: \"Doe\",\n * scores: [2, 4, 7]\n * };\n * var getIDAndLastScore = _.collect([_.getKey(\"id\"), _.getPath(\"scores.-1\")]);\n *\n * getIDAndLastScore(user) // => [\"jdoe\", 7]\n *\n * @example\n * var minAndMax = _.collect([Math.min, Math.max]);\n *\n * minAndMax(3, 1, -2, 5, 4, -1) // => [-2, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.35.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function collect (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n return map(functions, applyTo(arguments));\n };\n }\n\n /**\n * Used by curry functions to collect arguments until the arity is consumed,\n * then applies the original function.\n * @private\n * @param {Function} fn\n * @param {Number} arity\n * @param {Boolean} isRightCurry\n * @param {Boolean} isAutoCurry\n * @param {Array} argsHolder\n * @returns {Function}\n */\n function _currier (fn, arity, isRightCurry, isAutoCurry, argsHolder) {\n return function () {\n var holderLen = argsHolder.length;\n var argsLen = arguments.length;\n var newArgsLen = holderLen + (argsLen > 1 && isAutoCurry ? argsLen : 1);\n var newArgs = Array(newArgsLen);\n\n for (var i = 0; i < holderLen; i++) {\n newArgs[i] = argsHolder[i];\n }\n\n for (; i < newArgsLen; i++) {\n newArgs[i] = arguments[i - holderLen];\n }\n\n if (newArgsLen >= arity) {\n return fn.apply(this, isRightCurry ? newArgs.reverse() : newArgs);\n } else {\n return _currier(fn, arity, isRightCurry, isAutoCurry, newArgs);\n }\n };\n }\n\n /**\n * Curries a function of arity 3.\n * @private\n * @param {Function} fn\n * @param {Boolean} [isRightCurry=false]\n * @returns {Function}\n */\n function _curry3 (fn, isRightCurry) {\n return function (a) {\n return function (b) {\n return function (c) {\n return isRightCurry ? fn.call(this, c, b, a) : fn.call(this, a, b, c);\n };\n };\n };\n }\n\n /**\n * Prepares a function for currying. If it's not auto-currying and the arity\n * is 2 or 3 returns optimized functions, otherwise delegates the currying\n * to the _currier function.
\n * If the desumed arity isn't greater than one, it will return the received\n * function itself, instead.\n * @private\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @param {Boolean} [isRightCurry=false]\n * @param {Boolean} [isAutoCurry=false]\n * @returns {Function}\n */\n function _curry (fn, arity, isRightCurry, isAutoCurry) {\n if (arity >>> 0 !== arity) {\n arity = fn.length;\n }\n\n if (isAutoCurry && arity > 1 || arity > 3) {\n return _currier(fn, arity, isRightCurry, isAutoCurry, []);\n } else if (arity === 2) {\n return _curry2(fn, isRightCurry);\n } else if (arity === 3) {\n return _curry3(fn, isRightCurry);\n } else {\n return fn;\n }\n }\n\n /**\n * Transforms the evaluation of the given function in the evaluation of a sequence of functions\n * expecting only one argument. Each function of the sequence is a partial application of the\n * original one, which will be applied when the specified (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryRight|curryRight}\n * for right currying.\n * @example\n * var makeWithKeys = _.curry(_.make);\n * var makePerson = makeWithKeys([\"name\", \"surname\"]);\n *\n * makePerson([\"John\", \"Doe\"]) // => {name: \"John\", surname: \"Doe\"};\n * makePerson([\"Mario\", \"Rossi\"]) // => {name: \"Mario\", surname: \"Rossi\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curry (fn, arity) {\n return _curry(fn, arity, false);\n }\n\n /**\n * Builds an auto-curried function. The resulting function can be called multiple times with\n * any number of arguments, and the original function will be applied only when the specified\n * (or derived) arity is consumed.
\n * Currying will start from the leftmost argument: use {@link module:lamb.curryableRight|curryableRight}\n * for right currying.\n * @example\n * var collectFourElements = _.curryable(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2)(3, 4)(5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3, 4, 5) // => [2, 3, 4, 5]\n * collectFourElements(2, 3)(4, 5) // => [2, 3, 4, 5]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.6.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryable (fn, arity) {\n return _curry(fn, arity, false, true);\n }\n\n /**\n * Same as {@link module:lamb.curryable|curryable}, but currying starts from the rightmost argument.\n * @example\n * var collectFourElements = _.curryableRight(_.list, 4);\n *\n * collectFourElements(2)(3)(4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2)(3, 4)(5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3, 4, 5) // => [5, 4, 3, 2]\n * collectFourElements(2, 3)(4, 5) // => [5, 4, 3, 2]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curryable|curryable}\n * @see {@link module:lamb.curry|curry}, {@link module:lamb.curryRight|curryRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryableRight (fn, arity) {\n return _curry(fn, arity, true, true);\n }\n\n /**\n * Same as {@link module:lamb.curry|curry}, but currying starts from the rightmost argument.\n * @example\n * var makeWithValues = _.curryRight(_.make);\n * var makeJohnDoe = makeWithValues([\"John\", \"Doe\"]);\n *\n * makeJohnDoe([\"name\", \"surname\"]) // => {name: \"John\", surname: \"Doe\"};\n * makeJohnDoe([\"firstName\", \"lastName\"]) // => {firstName: \"John\", lastName: \"Doe\"};\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.curry|curry}\n * @see {@link module:lamb.curryable|curryable}, {@link module:lamb.curryableRight|curryableRight}\n * @see {@link module:lamb.partial|partial}, {@link module:lamb.partialRight|partialRight}\n * @see {@link module:lamb.asPartial|asPartial}\n * @since 0.9.0\n * @param {Function} fn\n * @param {Number} [arity=fn.length]\n * @returns {Function}\n */\n function curryRight (fn, arity) {\n return _curry(fn, arity, true);\n }\n\n /**\n * Returns a function that will execute the given function only if it stops being called for the\n * specified timespan.
\n * See also {@link module:lamb.throttle|throttle} for a different behaviour where the first call\n * happens immediately.\n * @example A common use case of debounce in a browser environment:\n * var updateLayout = function () {\n * // some heavy DOM operations here\n * };\n *\n * window.addEventListener(\"resize\", _.debounce(updateLayout, 200), false);\n *\n * // The resize event is fired repeteadly until the user stops resizing the\n * // window, while the `updateLayout` function is called only once: 200 ms\n * // after he stopped.\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.throttle|throttle}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds\n * @returns {Function}\n */\n function debounce (fn, timespan) {\n var timeoutID;\n\n return function () {\n var args = arguments;\n var debounced = function () {\n timeoutID = null;\n fn.apply(this, args);\n }.bind(this);\n\n clearTimeout(timeoutID);\n timeoutID = setTimeout(debounced, timespan);\n };\n }\n\n /**\n * Returns a function that applies the original function with the arguments in reverse order.\n * @example\n * _.list(1, 2, 3) // => [1, 2, 3]\n * _.flip(_.list)(1, 2, 3) // => [3, 2, 1]\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.1.0\n * @param {Function} fn\n * @returns {Function}\n */\n function flip (fn) {\n return function () {\n var args = list.apply(null, arguments).reverse();\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Builds a function that returns the argument received at the given index.
\n * As with {@link module:lamb.getAt|getAt} negative indexes are allowed.
\n * The resulting function will return undefined if no arguments are\n * passed or if the index is out of bounds.\n * @example\n * var getFirstArg = _.getArgAt(0);\n * var getLastArg = _.getArgAt(-1);\n *\n * getFirstArg(1, 2, 3) // => 1\n * getLastArg(1, 2, 3) // => 3\n *\n * _.getArgAt()(1, 2, 3) // => undefined\n * _.getArgAt(6)(1, 2, 3) // => undefined\n * _.getArgAt(1)() // => undefined\n *\n * @memberof module:lamb\n * @category Function\n * @since 0.17.0\n * @param {Number} idx\n * @returns {Function}\n */\n function getArgAt (idx) {\n return function () {\n return arguments[_toNaturalIndex(idx, arguments.length)];\n };\n }\n\n /* eslint-disable jsdoc/check-param-names */\n\n /**\n * If a method with the given name exists on the target, applies it to the provided\n * arguments and returns the result. Returns undefined otherwise.
\n * The arguments for the method are built by concatenating the array of bound arguments,\n * received by {@link module:lamb.invoker|invoker}, with the final set of args,\n * if present.\n * @private\n * @param {String} methodName\n * @param {Array} boundArgs\n * @param {Object} target\n * @param {...*} [args]\n * @returns {*}\n */\n function _invoker (methodName, boundArgs, target) {\n var method = target[methodName];\n\n if (typeof method !== \"function\") {\n return void 0;\n }\n\n var boundArgsLen = boundArgs ? _toArrayLength(boundArgs.length) : 0;\n var finalArgsLen = boundArgsLen + arguments.length - 3;\n var finalArgs = Array(finalArgsLen);\n\n for (var i = 0; i < boundArgsLen; i++) {\n finalArgs[i] = boundArgs[i];\n }\n\n for (var ofs = 3 - i; i < finalArgsLen; i++) {\n finalArgs[i] = arguments[i + ofs];\n }\n\n return method.apply(target, finalArgs);\n }\n\n /**\n * Builds a function that will invoke the given method name on any received object and\n * return the result. If no method with such name is found the function will return\n * undefined.
\n * Along with the method name it's possible to supply some arguments that will be bound to the\n * method call. Further arguments can also be passed when the function is actually called, and\n * they will be concatenated to the bound ones.
\n * Returning undefined is a behaviour meant to quickly create a case for\n * {@link module:lamb.adapter|adapter} without the need to check for the existence of the\n * desired method.
\n * See also {@link module:lamb.generic|generic} to create functions out of object methods.\n * @example Basic polymorphism with invoker:\n * var polySlice = _.invoker(\"slice\");\n *\n * polySlice([1, 2, 3, 4, 5], 1, 3) // => [2, 3]\n * polySlice(\"Hello world\", 1, 3) // => \"el\"\n *\n * @example With bound arguments:\n * var substrFrom2 = _.invoker(\"substr\", [2]);\n * substrFrom2(\"Hello world\") // => \"llo world\"\n * substrFrom2(\"Hello world\", 5) // => \"llo w\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invokerOn|invokerOn}\n * @since 0.1.0\n * @param {String} methodName\n * @param {ArrayLike} [boundArgs=[]]\n * @returns {Function}\n */\n function invoker (methodName, boundArgs) {\n return partial(_invoker, [methodName, boundArgs]);\n }\n\n /**\n * Accepts an object and builds a function expecting a method name, and optionally arguments,\n * to call on such object.\n * Like {@link module:lamb.invoker|invoker}, if no method with the given name is found the\n * function will return undefined.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var arr = [1, 2, 3, 4, 5];\n * var invokerOnArr = _.invokerOn(arr);\n *\n * invokerOnArr(\"filter\", isEven) // => [2, 4]\n * invokerOnArr(\"slice\", 1, 3) // => [2, 3]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.15.0\n * @param {Object} target\n * @returns {Function}\n */\n function invokerOn (target) {\n return partial(_invoker, [__, [], target]);\n }\n\n /**\n * Builds a function that allows to map over the received arguments before applying them\n * to the original one.\n * @example\n * var __ = _.__;\n * var sumArray = _.reduceWith(_.sum);\n * var sumArgs = _.compose(sumArray, _.list);\n *\n * sumArgs(1, 2, 3, 4, 5) // => 15\n *\n * var square = _.partial(Math.pow, [__, 2]);\n * var sumSquares = _.mapArgs(sumArgs, square);\n *\n * sumSquares(1, 2, 3, 4, 5) // => 55\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.tapArgs|tapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {ListIteratorCallback} mapper\n * @returns {Function}\n */\n function mapArgs (fn, mapper) {\n return pipe([list, mapWith(mapper), apply(fn)]);\n }\n\n /**\n * Builds a function that allows to \"tap\" into the arguments of the original one.\n * This allows to extract simple values from complex ones, transform arguments or simply intercept them.\n * If a \"tapper\" isn't found the argument is passed as it is.\n * @example\n * var someObject = {count: 5};\n * var someArrayData = [2, 3, 123, 5, 6, 7, 54, 65, 76, 0];\n * var getDataAmount = _.tapArgs(_.sum, [_.getKey(\"count\"), _.getKey(\"length\")]);\n *\n * getDataAmount(someObject, someArrayData); // => 15\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.mapArgs|mapArgs}\n * @since 0.3.0\n * @param {Function} fn\n * @param {Function[]} tappers\n * @returns {Function}\n */\n function tapArgs (fn, tappers) {\n return function () {\n var len = arguments.length;\n var tappersLen = tappers.length;\n var args = [];\n\n for (var i = 0; i < len; i++) {\n args.push(i < tappersLen ? tappers[i](arguments[i]) : arguments[i]);\n }\n\n return fn.apply(this, args);\n };\n }\n\n /**\n * Returns a function that will invoke the passed function at most once in the given timespan.
\n * The first call in this case happens as soon as the function is invoked; see also\n * {@link module:lamb.debounce|debounce} for a different behaviour where the first call is delayed.\n * @example\n * var log = _.throttle(console.log.bind(console), 5000);\n *\n * log(\"Hi\"); // console logs \"Hi\"\n * log(\"Hi again\"); // nothing happens\n * // after five seconds\n * log(\"Hello world\"); // console logs \"Hello world\"\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.debounce|debounce}\n * @since 0.1.0\n * @param {Function} fn\n * @param {Number} timespan - Expressed in milliseconds.\n * @returns {Function}\n */\n function throttle (fn, timespan) {\n var result;\n var lastCall = 0;\n\n return function () {\n var now = Date.now();\n\n if (now - lastCall >= timespan) {\n lastCall = now;\n result = fn.apply(this, arguments);\n }\n\n return result;\n };\n }\n\n /**\n * Builds a function that passes only one argument to the given function.
\n * It's simply a shortcut for a common use case of {@link module:lamb.aritize|aritize},\n * exposed for convenience.\n * @example\n * var weights = [\"2 Kg\", \"10 Kg\", \"1 Kg\", \"7 Kg\"];\n *\n * _.map(weights, _.unary(parseInt)) // => [2, 10, 1, 7]\n *\n * @memberof module:lamb\n * @category Function\n * @see {@link module:lamb.aritize|aritize}\n * @see {@link module:lamb.binary|binary}\n * @since 0.10.0\n * @param {Function} fn\n * @returns {Function}\n */\n function unary (fn) {\n return function (a) {\n return fn.call(this, a);\n };\n }\n\n /**\n * Accepts a series of functions and builds a function that applies the received\n * arguments to each one and returns the first non-undefined value.
\n * Meant to work in synergy with {@link module:lamb.case|case} and\n * {@link module:lamb.invoker|invoker}, can be useful as a strategy pattern for functions,\n * to mimic conditional logic or pattern matching, and also to build polymorphic functions.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var filterString = _.compose(_.joinWith(\"\"), _.filter);\n * var filterAdapter = _.adapter([\n * _.invoker(\"filter\"),\n * _.case(_.isType(\"String\"), filterString)\n * ]);\n *\n * filterAdapter([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterAdapter(\"123456\", isEven) // => \"246\"\n * filterAdapter({}, isEven) // => undefined\n *\n * // by its nature is composable\n * var filterWithDefault = _.adapter([filterAdapter, _.always(\"Not implemented\")]);\n *\n * filterWithDefault([1, 2, 3, 4, 5, 6], isEven) // => [2, 4, 6]\n * filterWithDefault(\"123456\", isEven) // => \"246\"\n * filterWithDefault({}, isEven) // => \"Not implemented\"\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.case|case}\n * @see {@link module:lamb.invoker|invoker}\n * @since 0.6.0\n * @param {Function[]} functions\n * @returns {Function}\n */\n function adapter (functions) {\n if (!Array.isArray(functions)) {\n throw _makeTypeErrorFor(functions, \"array\");\n }\n\n return function () {\n var len = functions.length;\n var result;\n\n for (var i = 0; i < len; i++) {\n result = functions[i].apply(this, arguments);\n\n if (!isUndefined(result)) {\n break;\n }\n }\n\n return result;\n };\n }\n\n /**\n * Creates a function to check the given predicates.
\n * Used to build the {@link module:lamb.allOf|allOf} and the\n * {@link module:lamb.anyOf|anyOf} functions.\n * @private\n * @param {Boolean} checkAll\n * @returns {Function}\n */\n function _checkPredicates (checkAll) {\n return function (predicates) {\n if (!Array.isArray(predicates)) {\n throw _makeTypeErrorFor(predicates, \"array\");\n }\n\n return function () {\n for (var i = 0, len = predicates.length, result; i < len; i++) {\n result = predicates[i].apply(this, arguments);\n\n if (checkAll && !result) {\n return false;\n } else if (!checkAll && result) {\n return true;\n }\n }\n\n return checkAll;\n };\n };\n }\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if they are all satisfied\n * by the same arguments. The functions in the array will be applied one at a time until a\n * false value is produced, which is returned immediately.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var isPositiveEven = _.allOf([isEven, _.isGT(0)]);\n *\n * isPositiveEven(-2) // => false\n * isPositiveEven(11) // => false\n * isPositiveEven(6) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.anyOf|anyOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var allOf = _checkPredicates(true);\n\n /**\n * Accepts an array of predicates and builds a new one that returns true if at least one of them is\n * satisfied by the received arguments. The functions in the array will be applied one at a time\n * until a true value is produced, which is returned immediately.\n * @example\n * var users = [\n * {id: 1, name: \"John\", group: \"guest\"},\n * {id: 2, name: \"Jane\", group: \"root\"},\n * {id: 3, name: \"Mario\", group: \"admin\"}\n * ];\n * var isInGroup = _.partial(_.hasKeyValue, [\"group\"]);\n * var isSuperUser = _.anyOf([isInGroup(\"admin\"), isInGroup(\"root\")]);\n *\n * isSuperUser(users[0]) // => false\n * isSuperUser(users[1]) // => true\n * isSuperUser(users[2]) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.allOf|allOf}\n * @since 0.1.0\n * @param {Function[]} predicates\n * @returns {Function}\n */\n var anyOf = _checkPredicates(false);\n\n /**\n * Verifies that the two supplied values are the same value using the \"SameValue\" comparison.
\n * Note that this doesn't behave as the strict equality operator, but rather as a shim of ES6's\n * [Object.is]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}.\n * Differences are that 0 and -0 aren't the same value and, finally,\n * NaN is equal to itself.
\n * See also {@link module:lamb.is|is} for a curried version building a predicate and\n * {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ} to perform a \"SameValueZero\"\n * comparison.\n * @example\n * var testObject = {};\n *\n * _.areSame({}, testObject) // => false\n * _.areSame(testObject, testObject) // => true\n * _.areSame(\"foo\", \"foo\") // => true\n * _.areSame(0, -0) // => false\n * _.areSame(0 / 0, NaN) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.is|is}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.50.0\n * @param {*} a\n * @param {*} b\n * @returns {Boolean}\n */\n function areSame (a, b) {\n return a === 0 && b === 0 ? 1 / a === 1 / b : areSVZ(a, b);\n }\n\n /**\n * Builds a case for {@link module:lamb.adapter|adapter}.
\n * The function will apply the received arguments to fn if the predicate is satisfied\n * with the same arguments, otherwise will return undefined.
\n * See also {@link module:lamb.condition|condition} to build a condition with two branching functions\n * and {@link module:lamb.unless|unless} and {@link module:lamb.when|when} where one of the branches\n * is the identity function.\n * @example\n * var halveIfNumber = _.case(_.isType(\"Number\"), _.divideBy(2));\n *\n * halveIfNumber(2) // => 1\n * halveIfNumber(\"2\") // => undefined\n *\n * @alias module:lamb.case\n * @category Logic\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @since 0.51.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function case_ (predicate, fn) {\n return function () {\n return predicate.apply(this, arguments) ? fn.apply(this, arguments) : void 0;\n };\n }\n\n /**\n * Builds a function that will apply the received arguments to trueFn,\n * if the predicate is satisfied with the same arguments, or to falseFn otherwise.
\n * Although you can use other conditions as trueFn or falseFn,\n * it's probably better to use {@link module:lamb.adapter|adapter} to build more complex behaviours.
\n * See also {@link module:lamb.unless|unless} and {@link module:lamb.when|when} as they are\n * shortcuts to common use cases.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveEvenAndDoubleOdd = _.condition(isEven, _.divideBy(2), _.multiplyBy(2));\n *\n * halveEvenAndDoubleOdd(5) // => 10\n * halveEvenAndDoubleOdd(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.2.0\n * @param {Function} predicate\n * @param {Function} trueFn\n * @param {Function} falseFn\n * @returns {Function}\n */\n function condition (predicate, trueFn, falseFn) {\n return function () {\n return (predicate.apply(this, arguments) ? trueFn : falseFn).apply(this, arguments);\n };\n }\n\n /**\n * Verifies that the first given value is greater than the second.
\n * Wraps the native > operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.gt(today, pastDate) // => true\n * _.gt(pastDate, today) // => false\n * _.gt(3, 4) // => false\n * _.gt(3, 3) // => false\n * _.gt(3, 2) // => true\n * _.gt(0, -0) // => false\n * _.gt(-0, 0) // => false\n * _.gt(\"a\", \"A\") // => true\n * _.gt(\"b\", \"a\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gt (a, b) {\n return a > b;\n }\n\n /**\n * Verifies that the first given value is greater than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * >= operator, so -0 === 0.\n * @example\n * _.gte(3, 4) // => false\n * _.gte(3, 3) // => true\n * _.gte(3, 2) // => true\n * _.gte(0, -0) // => true\n * _.gte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.gt|gt}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function gte (a, b) {\n return a >= b;\n }\n\n /**\n * A curried version of {@link module:lamb.areSame|areSame}.
\n * Accepts a value and builds a predicate that checks whether the value\n * and the one received by the predicate are the same using the \"SameValue\"\n * comparison.
\n * See also {@link module:lamb.areSVZ|areSVZ} and {@link module:lamb.isSVZ|isSVZ}\n * to perform a \"SameValueZero\" comparison.\n * @example\n * var john = {name: \"John\", surname: \"Doe\"};\n * var isJohn = _.is(john);\n * var isNegativeZero = _.is(-0);\n * var isReallyNaN = _.is(NaN);\n *\n * isJohn(john) // => true\n * isJohn({name: \"John\", surname: \"Doe\"}) // => false\n *\n * isNegativeZero(0) // => false\n * isNegativeZero(-0) // => true\n *\n * isNaN(NaN) // => true\n * isNaN(\"foo\") // => true\n *\n * isReallyNaN(NaN) // => true\n * isReallyNaN(\"foo\") // => false\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.areSame|areSame}\n * @see {@link module:lamb.areSVZ|areSVZ}, {@link module:lamb.isSVZ|isSVZ}\n * @see [SameValue comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevalue}\n * @see [SameValueZero comparison]{@link https://www.ecma-international.org/ecma-262/7.0/#sec-samevaluezero}\n * @since 0.1.0\n * @param {*} value\n * @returns {Function}\n */\n var is = _curry2(areSame);\n\n /**\n * A right curried version of {@link module:lamb.gt|gt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than the one received by the predicate.\n * @example\n * var isGreaterThan5 = _.isGT(5);\n *\n * isGreaterThan5(3) // => false\n * isGreaterThan5(5) // => false\n * isGreaterThan5(7) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGT = _curry2(gt, true);\n\n /**\n * A right curried version of {@link module:lamb.gte|gte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is greater than or equal to the one received by the predicate.\n * @example\n * var isPositiveOrZero = _.isGTE(0);\n *\n * isPositiveOrZero(-3) // => false\n * isPositiveOrZero(-0) // => true\n * isPositiveOrZero(0) // => true\n * isPositiveOrZero(5) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isGT|isGT}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isGTE = _curry2(gte, true);\n\n /**\n * Verifies that the first given value is less than the second.
\n * Wraps the native < operator within a function.\n * @example\n * var pastDate = new Date(2010, 2, 12);\n * var today = new Date();\n *\n * _.lt(today, pastDate) // => false\n * _.lt(pastDate, today) // => true\n * _.lt(3, 4) // => true\n * _.lt(3, 3) // => false\n * _.lt(3, 2) // => false\n * _.lt(0, -0) // => false\n * _.lt(-0, 0) // => false\n * _.lt(\"a\", \"A\") // => false\n * _.lt(\"a\", \"b\") // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lt (a, b) {\n return a < b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lt|lt}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than the one received by the predicate.\n * @example\n * var isLessThan5 = _.isLT(5);\n *\n * isLessThan5(7) // => false\n * isLessThan5(5) // => false\n * isLessThan5(3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLT = _curry2(lt, true);\n\n /**\n * Verifies that the first given value is less than or equal to the second.\n * Regarding equality, beware that this is simply a wrapper for the native\n * <= operator, so -0 === 0.\n * @example\n * _.lte(3, 4) // => true\n * _.lte(3, 3) // => true\n * _.lte(3, 2) // => false\n * _.lte(0, -0) // => true\n * _.lte(-0, 0) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.lt|lt}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @see {@link module:lamb.isLT|isLT}, {@link module:lamb.isLTE|isLTE}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @since 0.50.0\n * @param {Number|String|Date|Boolean} a\n * @param {Number|String|Date|Boolean} b\n * @returns {Boolean}\n */\n function lte (a, b) {\n return a <= b;\n }\n\n /**\n * A right curried version of {@link module:lamb.lte|lte}.
\n * Accepts a value and builds a predicate that checks whether the value\n * is less than or equal to the one received by the predicate.\n * @example\n * var isNegativeOrZero = _.isLTE(0);\n *\n * isNegativeOrZero(5) // => false\n * isNegativeOrZero(-0) // => true\n * isNegativeOrZero(0) // => true\n * isNegativeOrZero(-3) // => true\n *\n * @memberof module:lamb\n * @category Logic\n * @function\n * @see {@link module:lamb.isLT|isLT}\n * @see {@link module:lamb.isGT|isGT}, {@link module:lamb.isGTE|isGTE}\n * @see {@link module:lamb.lt|lt}, {@link module:lamb.lte|lte}\n * @see {@link module:lamb.gt|gt}, {@link module:lamb.gte|gte}\n * @since 0.1.0\n * @param {Number|String|Date|Boolean} value\n * @returns {Function}\n */\n var isLTE = _curry2(lte, true);\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate isn't satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.when|when} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its trueFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0};\n * var halveUnlessIsEven = _.unless(isEven, _.divideBy(2));\n *\n * halveUnlessIsEven(5) // => 2.5\n * halveUnlessIsEven(6) // => 6\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.when|when}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function unless (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? value : fn.call(this, value);\n };\n }\n\n /**\n * Builds a unary function that will check its argument against the given predicate.\n * If the predicate is satisfied, the provided fn function will be\n * applied to the same value. The received argument is returned as it is otherwise.
\n * See {@link module:lamb.unless|unless} for the opposite behaviour.
\n * It's a shortcut for a common use case of {@link module:lamb.condition|condition},\n * where its falseFn parameter is the [identity function]{@link module:lamb.identity}.\n * @example\n * var isEven = function (n) { return n % 2 === 0; };\n * var halveIfEven = _.when(isEven, _.divideBy(2));\n *\n * halveIfEven(5) // => 5\n * halveIfEven(6) // => 3\n *\n * @memberof module:lamb\n * @category Logic\n * @see {@link module:lamb.condition|condition}\n * @see {@link module:lamb.unless|unless}\n * @see {@link module:lamb.adapter|adapter}\n * @see {@link module:lamb.case|case}\n * @since 0.42.0\n * @param {Function} predicate\n * @param {Function} fn\n * @returns {Function}\n */\n function when (predicate, fn) {\n return function (value) {\n return predicate.call(this, value) ? fn.call(this, value) : value;\n };\n }\n\n /**\n * Sums two numbers.\n * @example\n * _.sum(4, 5) // => 9\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.add|add}\n * @since 0.50.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function sum (a, b) {\n return a + b;\n }\n\n /**\n * A curried version of {@link module:lamb.sum|sum}.\n * @example\n * var add5 = _.add(5);\n *\n * _.add5(4) // => 9\n * _.add5(-2) // => 3\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.sum|sum}\n * @since 0.1.0\n * @param {Number} a\n * @returns {Function}\n */\n var add = _curry2(sum, true);\n\n /**\n * Subtracts two numbers.\n * @example\n * _.subtract(5, 3) // => 2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.deduct|deduct}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function subtract (a, b) {\n return a - b;\n }\n\n /**\n * A curried version of {@link module:lamb.subtract|subtract} that expects the\n * subtrahend to build a function waiting for the minuend.\n * @example\n * var deduct5 = _.deduct(5);\n *\n * deduct5(12) // => 7\n * deduct5(3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.subtract|subtract}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var deduct = _curry2(subtract, true);\n\n /**\n * Divides two numbers.\n * @example\n * _.divide(5, 2) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.divideBy|divideBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function divide (a, b) {\n return a / b;\n }\n\n /**\n * A curried version of {@link module:lamb.divide|divide} that expects a divisor to\n * build a function waiting for the dividend.\n * @example\n * var halve = divideBy(2);\n *\n * halve(10) // => 5\n * halve(5) // => 2.5\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.divide|divide}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var divideBy = _curry2(divide, true);\n\n /**\n * Generates a sequence of values of the desired length with the provided iteratee.\n * The values being iterated, and received by the iteratee, are the results generated so far.\n * @example\n * var fibonacci = function (n, idx, results) {\n * return n + (results[idx - 1] || 0);\n * };\n *\n * _.generate(1, 10, fibonacci) // => [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.range|range}\n * @since 0.21.0\n * @param {*} start - The starting value\n * @param {Number} len - The desired length for the sequence\n * @param {ListIteratorCallback} iteratee\n * @returns {Array}\n */\n function generate (start, len, iteratee) {\n var result = [start];\n\n for (var i = 0, limit = len - 1; i < limit; i++) {\n result.push(iteratee(result[i], i, result));\n }\n\n return result;\n }\n\n /**\n * Verifies whether the received value is a finite number.
\n * Behaves almost as a shim of ES6's [Number.isFinite]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isFinite(5) // => true\n * _.isFinite(new Number(5)) // => true\n * _.isFinite(Infinity) // => false\n * _.isFinite(-Infinity) // => false\n * _.isFinite(\"5\") // => false\n * _.isFinite(NaN) // => false\n * _.isFinite(null) // => false\n *\n * @alias module:lamb.isFinite\n * @category Math\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isFinite_ (value) {\n return type(value) === \"Number\" && isFinite(value);\n }\n\n /**\n * Verifies whether the received value is a number and an integer.\n * Behaves almost as a shim of ES6's [Number.isInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isInteger(5) // => true\n * _.isInteger(new Number(5)) // => true\n * _.isInteger(2.5) // => false\n * _.isInteger(Infinity) // => false\n * _.isInteger(-Infinity) // => false\n * _.isInteger(\"5\") // => false\n * _.isInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isSafeInteger|isSafeInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isInteger (value) {\n return type(value) === \"Number\" && value % 1 === 0;\n }\n\n /**\n * Verifies whether the received value is a \"safe integer\", meaning that is a number and that\n * can be exactly represented as an IEEE-754 double precision number.\n * The safe integers consist of all integers from -(253 - 1) inclusive to\n * 253 - 1 inclusive.
\n * Behaves almost as a shim of ES6's [Number.isSafeInteger]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger},\n * but with a difference: it will return true even for Number object's instances.\n * @example\n * _.isSafeInteger(5) // => true\n * _.isSafeInteger(new Number(5)) // => true\n * _.isSafeInteger(Math.pow(2, 53) - 1) // => true\n * _.isSafeInteger(Math.pow(2, 53)) // => false\n * _.isSafeInteger(2e32) // => false\n * _.isSafeInteger(2.5) // => false\n * _.isSafeInteger(Infinity) // => false\n * _.isSafeInteger(-Infinity) // => false\n * _.isSafeInteger(\"5\") // => false\n * _.isSafeInteger(NaN) // => false\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.isInteger|isInteger}\n * @since 0.46.0\n * @param {*} value\n * @returns {Boolean}\n */\n function isSafeInteger (value) {\n return isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;\n }\n\n /**\n * Performs the modulo operation and should not be confused with the\n * {@link module:lamb.remainder|remainder}.\n * The function performs a floored division to calculate the result and not\n * a truncated one, hence the sign of the dividend is not kept, unlike the\n * {@link module:lamb.remainder|remainder}.\n * @example\n * _.modulo(5, 3) // => 2\n * _.remainder(5, 3) // => 2\n *\n * _.modulo(-5, 3) // => 1\n * _.remainder(-5, 3) // => -2\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.remainder|remainder}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function modulo (a, b) {\n return a - (b * Math.floor(a / b));\n }\n\n /**\n * Multiplies two numbers.\n * @example\n * _.multiply(5, 3) // => 15\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.multiplyBy|multiplyBy}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function multiply (a, b) {\n return a * b;\n }\n\n /**\n * A curried version of {@link module:lamb.multiply|multiply}.\n * @example\n * var double = _.multiplyBy(2);\n *\n * double(5) // => 10\n *\n * @memberof module:lamb\n * @category Math\n * @function\n * @see {@link module:lamb.multiply|multiply}\n * @since 0.50.0\n * @param {Number} a\n * @returns {Function}\n */\n var multiplyBy = _curry2(multiply, true);\n\n /**\n * Generates a random integer between two given integers, both included.\n * Note that no safety measure is taken if the provided arguments aren't integers, so\n * you may end up with unexpected (not really) results.\n * For example randomInt(0.1, 1.2) could be 2.\n * @example\n *\n * _.randomInt(1, 10) // => an integer >=1 && <= 10\n *\n * @memberof module:lamb\n * @category Math\n * @since 0.1.0\n * @param {Number} min\n * @param {Number} max\n * @returns {Number}\n */\n function randomInt (min, max) {\n return Math.floor(Math.random() * (max - min + 1) + min);\n }\n\n /**\n * Converts a value to a number and returns it if it's not NaN, otherwise\n * returns zero.\n * @private\n * @param {*} value\n * @returns {Number}\n */\n function _forceToNumber (value) {\n var n = +value;\n\n return n === n ? n : 0; // eslint-disable-line no-self-compare\n }\n\n /**\n * Generates an arithmetic progression of numbers starting from start up to,\n * but not including, limit, using the given step.\n * @example\n * _.range(2, 10) // => [2, 3, 4, 5, 6, 7, 8, 9]\n * _.range(1, -10, -2) // => [1, -1, -3, -5, -7, -9]\n * _.range(0, 3, 1) // => [0, 1, 2]\n * _.range(-0, 3, 1) // => [-0, 1, 2]\n * _.range(1, -10, 2) // => []\n * _.range(3, 5, -1) // => []\n *\n * @example Behaviour if step happens to be zero:\n * _.range(2, 10, 0) // => [2]\n * _.range(2, -10, 0) // => [2]\n * _.range(2, 2, 0) // => []\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.generate|generate}\n * @since 0.1.0\n * @param {Number} start\n * @param {Number} limit\n * @param {Number} [step=1]\n * @returns {Number[]}\n */\n function range (start, limit, step) {\n start = _forceToNumber(start);\n limit = _forceToNumber(limit);\n step = arguments.length === 3 ? _forceToNumber(step) : 1;\n\n if (step === 0) {\n return limit === start ? [] : [start];\n }\n\n var len = Math.max(Math.ceil((limit - start) / step), 0);\n var result = Array(len);\n\n for (var i = 0, last = start; i < len; i++) {\n result[i] = last;\n last += step;\n }\n\n return result;\n }\n\n /**\n * Gets the remainder of the division of two numbers.\n * Not to be confused with the {@link module:lamb.modulo|modulo} as the remainder\n * keeps the sign of the dividend and may lead to some unexpected results.\n * @example\n * // example of wrong usage of the remainder\n * // (in this case the modulo operation should be used)\n * var isOdd = function (n) { return _.remainder(n, 2) === 1; };\n * isOdd(-3) // => false as -3 % 2 === -1\n *\n * @memberof module:lamb\n * @category Math\n * @see {@link module:lamb.modulo|modulo}\n * @see [Modulo operation on Wikipedia]{@link http://en.wikipedia.org/wiki/Modulo_operation}\n * @since 0.1.0\n * @param {Number} a\n * @param {Number} b\n * @returns {Number}\n */\n function remainder (a, b) {\n return a % b;\n }\n\n /**\n * Checks whether the specified key is a own enumerable property of the given object or not.\n * @private\n * @function\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var _isOwnEnumerable = generic(Object.prototype.propertyIsEnumerable);\n\n /**\n * Builds a list of the enumerable properties of an object.\n * The function is null-safe, unlike the public one.\n * @private\n * @param {Object} obj\n * @returns {String[]}\n */\n function _safeEnumerables (obj) {\n var result = [];\n\n for (var key in obj) {\n result.push(key);\n }\n\n return result;\n }\n\n /**\n * Checks whether the specified key is an enumerable property of the given object or not.\n * @private\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function _isEnumerable (obj, key) {\n return key in Object(obj) && (_isOwnEnumerable(obj, key) || ~_safeEnumerables(obj).indexOf(key));\n }\n\n /**\n * Helper to retrieve the correct key while evaluating a path.\n * @private\n * @param {Object} target\n * @param {String} key\n * @param {Boolean} includeNonEnumerables\n * @returns {String|Number|Undefined}\n */\n function _getPathKey (target, key, includeNonEnumerables) {\n if (includeNonEnumerables && key in Object(target) || _isEnumerable(target, key)) {\n return key;\n }\n\n var n = +key;\n var len = target && target.length;\n\n return n >= -len && n < len ? n < 0 ? n + len : n : void 0;\n }\n\n /**\n * Checks if a path is valid in the given object and retrieves the path target.\n * @private\n * @param {Object} obj\n * @param {String[]} parts\n * @param {Boolean} walkNonEnumerables\n * @returns {Object}\n */\n function _getPathInfo (obj, parts, walkNonEnumerables) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n var target = obj;\n var i = -1;\n var len = parts.length;\n var key;\n\n while (++i < len) {\n key = _getPathKey(target, parts[i], walkNonEnumerables);\n\n if (isUndefined(key)) {\n break;\n }\n\n target = target[key];\n }\n\n return i === len ? { isValid: true, target: target } : { isValid: false, target: void 0 };\n }\n\n /**\n * Splits a sting path using the provided separator and returns an array\n * of path parts.\n * @private\n * @param {String} path\n * @param {String} separator\n * @returns {String[]}\n */\n function _toPathParts (path, separator) {\n return String(path).split(separator || \".\");\n }\n\n /**\n * Gets a nested property value from an object using the given path.
\n * The path is a string with property names separated by dots by default, but\n * it can be customised with the optional third parameter.
\n * You can use integers in the path, even negative ones, to refer to array-like\n * object indexes, but the priority will be given to existing object keys:\n * the last example explains this particular case.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * },\n * scores: [\n * {id: 1, value: 10},\n * {id: 2, value: 20},\n * {id: 3, value: 30}\n * ]\n * };\n *\n * _.getPathIn(user, \"name\") // => \"John\"\n * _.getPathIn(user, \"login.password\") // => \"abc123\";\n * _.getPathIn(user, \"login/user.name\", \"/\") // => \"jdoe\"\n * _.getPathIn(user, \"name.foo\") // => undefined\n * _.getPathIn(user, \"name.foo.bar\") // => undefined\n *\n * @example Accessing array-like objects indexes:\n * _.getPathIn(user, \"login.password.1\") // => \"b\"\n * _.getPathIn(user, \"scores.0\") // => {id: 1, value: 10}\n * _.getPathIn(user, \"scores.-1.value\") // => 30\n *\n * @example Priority will be given to existing object keys over indexes:\n * _.getPathIn(user, \"scores.-1\") // => {id: 3, value: 30}\n *\n * // let's do something funny\n * user.scores[\"-1\"] = \"foo bar\";\n *\n * _.getPathIn(user, \"scores.-1\") // => \"foo bar\";\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.getPath|getPath}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {Object|ArrayLike} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {*}\n */\n function getPathIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).target;\n }\n\n /**\n * Builds a checker function meant to be used with\n * {@link module:lamb.validate|validate}.
\n * Note that the function accepts multiple keyPaths as a means to\n * compare their values. In other words all the received keyPaths will be\n * passed as arguments to the predicate to run the test.
\n * If you want to run the same single property check with multiple properties, you should build\n * multiple checkers and combine them with {@link module:lamb.validate|validate}.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * username: \"jdoe\",\n * password: \"abc123\",\n * passwordConfirm: \"abc123\"\n * }\n * };\n * var pwdMatch = _.checker(\n * _.areSame,\n * \"Passwords don't match\",\n * [\"login.password\", \"login.passwordConfirm\"]\n * );\n *\n * pwdMatch(user) // => []\n *\n * var newUser = _.setPathIn(user, \"login.passwordConfirm\", \"avc123\");\n *\n * pwdMatch(newUser) // => [\"Passwords don't match\", [\"login.password\", \"login.passwordConfirm\"]]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validate|validate}, {@link module:lamb.validateWith|validateWith}\n * @since 0.1.0\n * @param {Function} predicate - The predicate to test the object properties\n * @param {String} message - The error message\n * @param {String[]} keyPaths - The array of keys, or {@link module:lamb.getPathIn|paths}, to test.\n * @param {String} [pathSeparator=\".\"]\n * @returns {Function} A checker function which returns an error in the form\n * [\"message\", [\"propertyA\", \"propertyB\"]] or an empty array.\n */\n function checker (predicate, message, keyPaths, pathSeparator) {\n return function (obj) {\n var getValues = partial(getPathIn, [obj, __, pathSeparator]);\n\n return predicate.apply(obj, map(keyPaths, getValues)) ? [] : [message, keyPaths];\n };\n }\n\n /**\n * Creates a non-null-safe version of the provided \"getKeys\" function.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _unsafeKeyListFrom = _curry2(function (getKeys, obj) {\n if (isNil(obj)) {\n throw _makeTypeErrorFor(obj, \"object\");\n }\n\n return getKeys(obj);\n });\n\n /**\n * Creates an array with all the enumerable properties of the given object.\n * @example Showing the difference with {@link module:lamb.keys|keys}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.keys(foo) // => [\"d\"]\n * _.enumerables(foo) // => [\"d\", \"a\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.keys|keys}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {String[]}\n */\n var enumerables = _unsafeKeyListFrom(_safeEnumerables);\n\n /**\n * Builds an object from a list of key / value pairs like the one\n * returned by {@link module:lamb.pairs|pairs} or {@link module:lamb.ownPairs|ownPairs}.
\n * In case of duplicate keys the last key / value pair is used.\n * @example\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"c\", 3]]) // => {\"a\": 1, \"b\": 2, \"c\": 3}\n * _.fromPairs([[\"a\", 1], [\"b\", 2], [\"a\", 3]]) // => {\"a\": 3, \"b\": 2}\n * _.fromPairs([[1], [void 0, 2], [null, 3]]) // => {\"1\": undefined, \"undefined\": 2, \"null\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.ownPairs|ownPairs}, {@link module:lamb.pairs|pairs}\n * @since 0.8.0\n * @param {Array>} pairsList\n * @returns {Object}\n */\n function fromPairs (pairsList) {\n var result = {};\n\n forEach(pairsList, function (pair) {\n result[pair[0]] = pair[1];\n });\n\n return result;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.getPathIn|getPathIn} with the given\n * path and separator, expecting the object to act upon.
\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * login: {\n * \"user.name\": \"jdoe\",\n * password: \"abc123\"\n * }\n * };\n *\n * var getPwd = _.getPath(\"login.password\");\n * var getUsername = _.getPath(\"login/user.name\", \"/\");\n *\n * getPwd(user) // => \"abc123\";\n * getUsername(user) // => \"jdoe\"\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.getPathIn|getPathIn}\n * @see {@link module:lamb.getIn|getIn}, {@link module:lamb.getKey|getKey}\n * @since 0.19.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var getPath = _makePartial3(getPathIn);\n\n /**\n * Verifies the existence of a property in an object.\n * @example\n * var user1 = {name: \"john\"};\n *\n * _.has(user1, \"name\") // => true\n * _.has(user1, \"surname\") // => false\n * _.has(user1, \"toString\") // => true\n *\n * var user2 = Object.create(null);\n *\n * // not inherited through the prototype chain\n * _.has(user2, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n function has (obj, key) {\n if (typeof obj !== \"object\" && !isUndefined(obj)) {\n obj = Object(obj);\n }\n\n return key in obj;\n }\n\n /**\n * Curried version of {@link module:lamb.has|has}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user1 = {name: \"john\"};\n * var user2 = {};\n * var hasName = _.hasKey(\"name\");\n *\n * hasName(user1) // => true\n * hasName(user2) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.has|has}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasKey = _curry2(has, true);\n\n /**\n * Verifies if an object has the specified property and that the property isn't inherited through\n * the prototype chain.
\n * @example Comparison with has:\n * var user = {name: \"john\"};\n *\n * _.has(user, \"name\") // => true\n * _.has(user, \"surname\") // => false\n * _.has(user, \"toString\") // => true\n *\n * _.hasOwn(user, \"name\") // => true\n * _.hasOwn(user, \"surname\") // => false\n * _.hasOwn(user, \"toString\") // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {Object} obj\n * @param {String} key\n * @returns {Boolean}\n */\n var hasOwn = generic(Object.prototype.hasOwnProperty);\n\n /**\n * Curried version of {@link module:lamb.hasOwn|hasOwn}.
\n * Returns a function expecting the object to check against the given key.\n * @example\n * var user = {name: \"john\"};\n * var hasOwnName = _.hasOwnKey(\"name\");\n * var hasOwnToString = _.hasOwnToString(\"toString\");\n *\n * hasOwnName(user) // => true\n * hasOwnToString(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.hasOwn|hasOwn}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}, {@link module:lamb.pathExists|pathExists}\n * @since 0.1.0\n * @param {String} key\n * @returns {Function}\n */\n var hasOwnKey = _curry2(hasOwn, true);\n\n /**\n * Builds a predicate expecting an object to check against the given key / value pair.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.\n * @example\n * var hasTheCorrectAnswer = _.hasKeyValue(\"answer\", 42);\n *\n * hasTheCorrectAnswer({answer: 2}) // false\n * hasTheCorrectAnswer({answer: 42}) // true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasPathValue|hasPathValue}\n * @since 0.1.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n function hasKeyValue (key, value) {\n return function (obj) {\n return isUndefined(value) ? has(obj, key) && obj[key] === value : areSVZ(value, obj[key]);\n };\n }\n\n /**\n * Builds a predicate to check if the given path exists in an object and holds the desired value.
\n * The value check is made with the [\"SameValueZero\" comparison]{@link module:lamb.areSVZ|areSVZ}.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * personal: {\n * age: 25,\n * gender: \"M\"\n * },\n * scores: [\n * {id: 1, value: 10, passed: false},\n * {id: 2, value: 20, passed: false},\n * {id: 3, value: 30, passed: true}\n * ]\n * };\n *\n * var isMale = _.hasPathValue(\"personal.gender\", \"M\");\n * var hasPassedFirstTest = _.hasPathValue(\"scores.0.passed\", true);\n * var hasPassedLastTest = _.hasPathValue(\"scores.-1.passed\", true);\n *\n * isMale(user) // => true\n * hasPassedFirstTest(user) // => false\n * hasPassedLastTest(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.hasKeyValue|hasKeyValue}\n * @since 0.41.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function hasPathValue (path, value, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return pathInfo.isValid && areSVZ(pathInfo.target, value);\n };\n }\n\n /**\n * A null-safe version of Object.keys.\n * @private\n * @function\n * @param {Object} obj\n * @returns {String[]}\n */\n var _safeKeys = compose(Object.keys, Object);\n\n /**\n * Retrieves the list of the own enumerable properties of an object.
\n * Although [Object.keys]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys}\n * is already present in ECMAScript 5, its behaviour changed in the subsequent specifications\n * of the standard.
\n * This function shims the ECMAScript 6 version, by forcing a conversion to\n * object for any value but null and undefined.\n * @example Showing the difference with {@link module:lamb.enumerables|enumerables}:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3},\n * d: {value: 4, enumerable: true}\n * });\n *\n * _.enumerables(foo) // => [\"d\", \"a\"]\n * _.keys(foo) // => [\"d\"]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.enumerables|enumerables}\n * @since 0.25.1\n * @param {Object} obj\n * @returns {String[]}\n */\n var keys = _unsafeKeyListFrom(_safeKeys);\n\n /**\n * Builds a predicate to check if the given key satisfies the desired condition\n * on an object.\n * @example\n * var users = [\n * {name: \"John\", age: 25},\n * {name: \"Jane\", age: 15},\n * ];\n * var isAdult = _.keySatisfies(_.isGTE(18), \"age\");\n *\n * isAdult(users[0]) // => true\n * isAdult(users[1]) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathSatisfies|pathSatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} key\n * @returns {Function}\n */\n function keySatisfies (predicate, key) {\n return function (obj) {\n return predicate.call(this, obj[key]);\n };\n }\n\n /**\n * Builds an object from the two given lists, using the first one as keys and the last\n * one as values.
\n * If the list of keys is longer than the values one, the keys will be created with\n * undefined values.
\n * If more values than keys are supplied, the extra values will be ignored.\n * @example\n * _.make([\"a\", \"b\", \"c\"], [1, 2, 3]) // => {a: 1, b: 2, c: 3}\n * _.make([\"a\", \"b\", \"c\"], [1, 2]) // => {a: 1, b: 2, c: undefined}\n * _.make([\"a\", \"b\"], [1, 2, 3]) // => {a: 1, b: 2}\n * _.make([null, void 0, 2], [1, 2, 3]) // => {\"null\": 1, \"undefined\": 2, \"2\": 3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.tear|tear}, {@link module:lamb.tearOwn|tearOwn} for the reverse operation\n * @since 0.8.0\n * @param {String[]} names\n * @param {ArrayLike} values\n * @returns {Object}\n */\n function make (names, values) {\n var result = {};\n var valuesLen = values.length;\n\n for (var i = 0, len = names.length; i < len; i++) {\n result[names[i]] = i < valuesLen ? values[i] : void 0;\n }\n\n return result;\n }\n\n /**\n * Creates a new object by applying the given function\n * to all enumerable properties of the source one.\n * @example\n * var weights = {\n * john: \"72.5 Kg\",\n * jane: \"52.3 Kg\"\n * };\n *\n * _.mapValues(weights, parseFloat) // => {john: 72.5, jane: 52.3}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValuesWith|mapValuesWith}\n * @since 0.54.0\n * @param {Object} source\n * @param {ObjectIteratorCallback} fn\n * @returns {Object}\n */\n function mapValues (source, fn) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n result[key] = fn(source[key], key, source);\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.mapValues|mapValues}.
\n * Expects a mapping function to build a new function waiting for the\n * object to act upon.\n * @example\n * var incValues = _.mapValuesWith(_.add(1));\n * var results = {\n * first: 10,\n * second: 5,\n * third: 3\n * };\n *\n * incValues(results) // => {first: 11, second: 6, third: 4}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mapValues|mapValues}\n * @since 0.54.0\n * @function\n * @param {ObjectIteratorCallback} fn\n * @returns {Function}\n */\n var mapValuesWith = _curry2(mapValues, true);\n\n /**\n * Merges the received objects using the provided function to retrieve their keys.\n * @private\n * @param {Function} getKeys\n * @param {Object} a\n * @param {Object} b\n * @returns {Function}\n */\n function _merge (getKeys, a, b) {\n return reduce([a, b], function (result, source) {\n forEach(getKeys(source), function (key) {\n result[key] = source[key];\n });\n\n return result;\n }, {});\n }\n\n /**\n * Merges the enumerable properties of the provided sources into a new object.
\n * In case of key homonymy the last source has precedence over the first.\n * @example\n * _.merge({a: 1, b: 3}, {b: 5, c: 4}) // => {a: 1, b: 5, c: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.merge([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.merge(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.merge({a: 2}, 99) // => {a: 2}\n * _.merge({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.mergeOwn|mergeOwn} to merge own properties only\n * @since 0.10.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var merge = partial(_merge, [enumerables]);\n\n /**\n * Same as {@link module:lamb.merge|merge}, but only the own properties of the\n * sources are taken into account.\n * @example Showing the difference with merge:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * var bar = {d: 4};\n *\n * _.merge(foo, bar) // => {a: 1, b: 2, c: 3, d: 4}\n * _.mergeOwn(foo, bar) // => {c: 3, d: 4}\n *\n * @example Array-like objects will be transformed to objects with numbers as keys:\n * _.mergeOwn([1, 2], {a: 2}) // => {\"0\": 1, \"1\": 2, a: 2}\n * _.mergeOwn(\"foo\", {a: 2}) // => {\"0\": \"f\", \"1\": \"o\", \"2\": \"o\", a: 2}\n *\n * @example Every other non-nil value will be treated as an empty object:\n * _.mergeOwn({a: 2}, 99) // => {a: 2}\n * _.mergeOwn({a: 2}, NaN) // => {a: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.merge|merge} to merge all enumerable properties\n * @since 0.12.0\n * @function\n * @param {Object} a\n * @param {Object} b\n * @returns {Object}\n */\n var mergeOwn = partial(_merge, [keys]);\n\n /**\n * Accepts an object and build a function expecting a key to create a \"pair\" with the key\n * and its value.\n * @private\n * @function\n * @param {Object} obj\n * @returns {Function}\n */\n var _keyToPairIn = _curry2(function (obj, key) {\n return [key, obj[key]];\n });\n\n /**\n * Using the provided function to retrieve the keys, builds a new function\n * expecting an object to create a list of key / value pairs.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _pairsFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), _keyToPairIn(obj));\n });\n\n /**\n * Same as {@link module:lamb.pairs|pairs}, but only the own enumerable properties of the object are\n * taken into account.
\n * See also {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example Showing the difference with pairs:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.pairs(foo) // => [[\"c\", 3], [\"b\", 2], [\"a\", 1]]\n * _.ownPairs(foo) // => [[\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pairs|pairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var ownPairs = _pairsFrom(keys);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create the list of values for such keys.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _valuesFrom = _curry2(function (getKeys, obj) {\n return map(getKeys(obj), function (key) {\n return obj[key];\n });\n });\n\n /**\n * Same as {@link module:lamb.values|values}, but only the own enumerable properties of the object are\n * taken into account.
\n * @example Showing the difference with values:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.values(foo) // => [3, 2, 1]\n * _.ownValues(foo) // => [3]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.values|values}\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var ownValues = _valuesFrom(keys);\n\n /**\n * Converts an object into an array of key / value pairs of its enumerable properties.
\n * See also {@link module:lamb.ownPairs|ownPairs} for picking only the own enumerable\n * properties and {@link module:lamb.fromPairs|fromPairs} for the reverse operation.\n * @example\n * _.pairs({a: 1, b: 2, c: 3}) // => [[\"a\", 1], [\"b\", 2], [\"c\", 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownPairs|ownPairs}\n * @see {@link module:lamb.fromPairs|fromPairs}\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array>}\n */\n var pairs = _pairsFrom(enumerables);\n\n /**\n * Checks if the provided path exists in the given object.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * _.pathExistsIn(user, \"address.city\") // => true\n * _.pathExistsIn(user, \"address.country\") // => false\n * _.pathExistsIn(user, \"scores.1\") // => true\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pathExists|pathExists}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {Object} obj\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Boolean}\n */\n function pathExistsIn (obj, path, separator) {\n return _getPathInfo(obj, _toPathParts(path, separator), true).isValid;\n }\n\n /**\n * Builds a partial application of {@link module:lamb.pathExistsIn|pathExistsIn} using the given\n * path and the optional separator. The resulting function expects the object to check.
\n * Note that the function will check even non-enumerable properties.\n * @example\n * var user = {\n * name: \"John\",\n * surname: \"Doe\",\n * address: {\n * city: \"New York\"\n * },\n * scores: [10, 20, 15]\n * };\n *\n * var hasCity = _.pathExists(\"address.city\");\n * var hasCountry = _.pathExists(\"address.country\");\n * var hasAtLeastThreeScores = _.pathExists(\"scores.2\");\n *\n * hasCity(user) // => true\n * hasCountry(user) // => false\n * hasAtLeastThreeScores(user) // => true\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pathExistsIn|pathExistsIn}\n * @see {@link module:lamb.hasOwn|hasOwn}, {@link module:lamb.hasOwnKey|hasOwnKey}\n * @see {@link module:lamb.has|has}, {@link module:lamb.hasKey|hasKey}\n * @since 0.43.0\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n var pathExists = _makePartial3(pathExistsIn);\n\n /**\n * Builds a predicate that verifies if a condition is satisfied for the given\n * path in an object.
\n * Like the other \"path functions\" you can use integers in the path, even\n * negative ones, to refer to array-like object indexes, but the priority will\n * be given to existing object keys.\n * @example\n * var user = {\n * name: \"John\",\n * performance: {\n * scores: [1, 5, 10]\n * }\n * };\n *\n * var gotAnHighScore = _.pathSatisfies(_.contains(10), \"performance.scores\");\n * var hadAGoodStart = _.pathSatisfies(_.isGT(6), \"performance.scores.0\");\n *\n * gotAnHighScore(user) // => true\n * hadAGoodStart(user) // => false\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.keySatisfies|keySatisfies}\n * @since 0.45.0\n * @param {Function} predicate\n * @param {String} path\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function pathSatisfies (predicate, path, separator) {\n return function (obj) {\n var pathInfo = _getPathInfo(obj, _toPathParts(path, separator), true);\n\n return predicate.call(this, pathInfo.target);\n };\n }\n\n /**\n * Returns an object containing only the specified properties of the given object.
\n * Non existent properties will be ignored.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.pick(user, [\"name\", \"age\"]) // => {\"name\": \"john\", \"age\": 30};\n * _.pick(user, [\"name\", \"email\"]) // => {\"name\": \"john\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pickIf|pickIf}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} whitelist\n * @returns {Object}\n */\n function pick (source, whitelist) {\n var result = {};\n\n for (var i = 0, len = whitelist.length, key; i < len; i++) {\n key = whitelist[i];\n\n if (has(source, key)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be included in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var pickIfIsString = _.pickIf(_.isType(\"String\"));\n *\n * pickIfIsString(user) // => {name: \"john\", surname: \"doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n function pickIf (predicate) {\n return function (source) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n\n for (var key in source) {\n if (predicate(source[key], key, source)) {\n result[key] = source[key];\n }\n }\n\n return result;\n };\n }\n\n /**\n * A curried version of {@link module:lamb.pick|pick}, expecting a whitelist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.pickKeys([\"id\", \"active\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var select = _.compose(_.mapWith, _.pickKeys);\n * var selectUserInfo = select([\"id\", \"active\"]);\n *\n * selectUserInfo(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickIf|pickIf}\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys},\n * {@link module:lamb.skipIf|skipIf}\n * @since 0.35.0\n * @param {String[]} whitelist\n * @returns {Function}\n */\n var pickKeys = _curry2(pick, true);\n\n /**\n * Creates a copy of the given object with its enumerable keys renamed as\n * indicated in the provided lookup table.\n * @example\n * var person = {\"firstName\": \"John\", \"lastName\": \"Doe\"};\n * var keysMap = {\"firstName\": \"name\", \"lastName\": \"surname\"};\n *\n * _.rename(person, keysMap) // => {\"name\": \"John\", \"surname\": \"Doe\"}\n *\n * @example It's safe using it to swap keys:\n * var keysMap = {\"firstName\": \"lastName\", \"lastName\": \"firstName\"};\n *\n * _.rename(person, keysMap) // => {\"lastName\": \"John\", \"firstName\": \"Doe\"}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.renameKeys|renameKeys}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} source\n * @param {Object} keysMap\n * @returns {Object}\n */\n function rename (source, keysMap) {\n keysMap = Object(keysMap);\n var result = {};\n var oldKeys = enumerables(source);\n\n for (var prop in keysMap) {\n if (~oldKeys.indexOf(prop)) {\n result[keysMap[prop]] = source[prop];\n }\n }\n\n for (var i = 0, len = oldKeys.length, key; i < len; i++) {\n key = oldKeys[i];\n\n if (!(key in keysMap || key in result)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * A curried version of {@link module:lamb.rename|rename} expecting a\n * keysMap to build a function waiting for the object to act upon.\n * @example\n * var persons = [\n * {\"firstName\": \"John\", \"lastName\": \"Doe\"},\n * {\"first_name\": \"Mario\", \"last_name\": \"Rossi\"},\n * ];\n * var normalizeKeys = _.renameKeys({\n * \"firstName\": \"name\",\n * \"first_name\": \"name\",\n * \"lastName\": \"surname\",\n * \"last_name\": \"surname\"\n * });\n *\n * _.map(persons, normalizeKeys) // =>\n * // [\n * // {\"name\": \"John\", \"surname\": \"Doe\"},\n * // {\"name\": \"Mario\", \"surname\": \"Rossi\"}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameWith|renameWith}\n * @since 0.26.0\n * @param {Object} keysMap\n * @returns {Function}\n */\n var renameKeys = _curry2(rename, true);\n\n /**\n * Uses the provided function as a keysMap generator and returns\n * a function expecting the object whose keys we want to {@link module:lamb.rename|rename}.\n * @example\n * var person = {\"NAME\": \"John\", \"SURNAME\": \"Doe\"};\n * var arrayToLower = _.mapWith(_.invoker(\"toLowerCase\"));\n * var makeLowerKeysMap = function (source) {\n * var sourceKeys = _.keys(source);\n *\n * return _.make(sourceKeys, arrayToLower(sourceKeys));\n * };\n * var lowerKeysFor = _.renameWith(makeLowerKeysMap);\n *\n * lowerKeysFor(person) // => {\"name\": \"John\", \"surname\": \"doe\"};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.rename|rename}, {@link module:lamb.renameKeys|renameKeys}\n * @since 0.26.0\n * @param {Function} fn\n * @returns {Function}\n */\n function renameWith (fn) {\n return function (source) {\n return rename(source, fn(source));\n };\n }\n\n /**\n * Sets, or creates, a property in a copy of the provided object to the desired value.\n * @private\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function _setIn (source, key, value) {\n var result = {};\n\n for (var prop in source) {\n result[prop] = source[prop];\n }\n\n result[key] = value;\n\n return result;\n }\n\n /**\n * Sets the specified key to the given value in a copy of the provided object.
\n * All the remaining enumerable keys of the source object will be simply copied in the\n * result object without breaking references.
\n * If the specified key is not part of the source object, it will be added to the\n * result.
\n * The main purpose of the function is to work on simple plain objects used as\n * data structures, such as JSON objects, and makes no effort to play nice with\n * objects created from an OOP perspective (it's not worth it).
\n * For example the prototype of the result will be Object's regardless\n * of the source's one.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n *\n * _.setIn(user, \"name\", \"Jane\") // => {name: \"Jane\", surname: \"Doe\", age: 30}\n * _.setIn(user, \"gender\", \"male\") // => {name: \"John\", surname: \"Doe\", age: 30, gender: \"male\"}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setKey|setKey}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {Object} source\n * @param {String} key\n * @param {*} value\n * @returns {Object}\n */\n function setIn (source, key, value) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setIn(source, key, value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setIn|setIn} with the provided\n * key and value.
\n * The resulting function expects the object to act upon.
\n * Please refer to {@link module:lamb.setIn|setIn}'s description for explanations about\n * how the copy of the source object is made.\n * @example\n * var user = {name: \"John\", surname: \"Doe\", age: 30};\n * var setAgeTo40 = _.setKey(\"age\", 40);\n *\n * setAgeTo40(user) // => {name: \"john\", surname: \"doe\", age: 40}\n *\n * // `user` still is {name: \"John\", surname: \"Doe\", age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.setIn|setIn}\n * @see {@link module:lamb.setPath|setPath}, {@link module:lamb.setPathIn|setPathIn}\n * @since 0.18.0\n * @param {String} key\n * @param {*} value\n * @returns {Function}\n */\n var setKey = _makePartial3(setIn);\n\n /**\n * Accepts a target object and a key name and verifies that the target is an array and that\n * the key is an existing index.\n * @private\n * @param {Object} target\n * @param {String|Number} key\n * @returns {Boolean}\n */\n function _isArrayIndex (target, key) {\n var n = +key;\n\n return Array.isArray(target) && n % 1 === 0 && !(n < 0 && _isEnumerable(target, key));\n }\n\n /**\n * Sets the object's property targeted by the given path to the desired value.
\n * Works with arrays and is able to set their indexes, even negative ones.\n * @private\n * @param {Object|Array} obj\n * @param {String[]} parts\n * @param {*} value\n * @returns {Object|Array}\n */\n function _setPathIn (obj, parts, value) {\n var key = parts[0];\n var partsLen = parts.length;\n var v;\n\n if (partsLen === 1) {\n v = value;\n } else {\n var targetKey = _getPathKey(obj, key, false);\n\n v = _setPathIn(\n isUndefined(targetKey) ? targetKey : obj[targetKey],\n slice(parts, 1, partsLen),\n value\n );\n }\n\n return _isArrayIndex(obj, key) ? _setIndex(obj, key, v) : _setIn(obj, key, v);\n }\n\n /**\n * Allows to change a nested value in a copy of the provided object.
\n * The function will delegate the \"set action\" to {@link module:lamb.setIn|setIn} or\n * {@link module:lamb.setAt|setAt} depending on the value encountered in the path,\n * so please refer to the documentation of those functions for specifics about the\n * implementation.
\n * Note anyway that the distinction will be between Arrays, delegated\n * to {@link module:lamb.setAt|setAt}, and everything else (including array-like objects),\n * which will be delegated to {@link module:lamb.setIn|setIn}.
\n * As a result of that, array-like objects will be converted to objects having numbers as keys\n * and paths targeting non-object values will be converted to empty objects.
\n * You can anyway target array elements using integers in the path, even negative ones, but\n * the priority will be given to existing, and enumerable, object keys.
\n * Non-enumerable properties encountered in the path will be considered as non-existent properties.
\n * Like {@link module:lamb.getPathIn|getPathIn} or {@link module:lamb.getPath|getPath} you can\n * use custom path separators.\n * @example\n * var user = {id: 1, status: {active : false, scores: [2, 4, 6]}};\n *\n * _.setPathIn(user, \"status.active\", true) // => {id: 1, status: {active : true, scores: [2, 4, 6]}}\n *\n * @example Targeting arrays:\n * _.setPathIn(user, \"status.scores.0\", 8) // => {id: 1, status: {active : false, scores: [8, 4, 6]}}\n *\n * // you can use negative indexes as well\n * _.setPathIn(user, \"status.scores.-1\", 8) // => {id: 1, status: {active : false, scores: [2, 4, 8]}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.setPathIn(user, \"scores.0.value\", 8);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 8, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPath|setPath}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function setPathIn (source, path, value, separator) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n return _setPathIn(source, _toPathParts(path, separator), value);\n }\n\n /**\n * Builds a partial application of {@link module:lamb.setPathIn|setPathIn} expecting the\n * object to act upon.
\n * See {@link module:lamb.setPathIn|setPathIn} for more details and examples.\n * @example\n * var user = {id: 1, status: {active: false}};\n * var activate = _.setPath(\"status.active\", true);\n *\n * activate(user) // => {id: 1, status: {active: true}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.setPathIn|setPathIn}\n * @see {@link module:lamb.setIn|setIn}, {@link module:lamb.setKey|setKey}\n * @since 0.20.0\n * @param {String} path\n * @param {*} value\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function setPath (path, value, separator) {\n return function (source) {\n return setPathIn(source, path, value, separator);\n };\n }\n\n /**\n * Returns a copy of the source object without the specified properties.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.skip(user, [\"name\", \"age\"]) // => {surname: \"doe\"};\n * _.skip(user, [\"name\", \"email\"]) // => {surname: \"doe\", age: 30};\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.skipKeys|skipKeys}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {Object} source\n * @param {String[]} blacklist\n * @returns {Object}\n */\n function skip (source, blacklist) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"object\");\n }\n\n var result = {};\n var props = make(blacklist, []);\n\n for (var key in source) {\n if (!(key in props)) {\n result[key] = source[key];\n }\n }\n\n return result;\n }\n\n /**\n * Builds a function expecting an object whose enumerable properties will be checked\n * against the given predicate.
\n * The properties satisfying the predicate will be omitted in the resulting object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n * var skipIfIstring = _.skipIf(_.isType(\"String\"));\n *\n * skipIfIstring(user) // => {age: 30}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipKeys|skipKeys}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.1.0\n * @param {ObjectIteratorCallback} predicate\n * @returns {Function}\n */\n var skipIf = compose(pickIf, not);\n\n /**\n * A curried version of {@link module:lamb.skip|skip}, expecting a blacklist of keys to build\n * a function waiting for the object to act upon.\n * @example\n * var user = {id: 1, name: \"Jane\", surname: \"Doe\", active: false};\n * var getUserInfo = _.skipKeys([\"name\", \"surname\"]);\n *\n * getUserInfo(user) // => {id: 1, active: false}\n *\n * @example A useful composition with mapWith:\n * var users = [\n * {id: 1, name: \"Jane\", surname: \"Doe\", active: false},\n * {id: 2, name: \"John\", surname: \"Doe\", active: true},\n * {id: 3, name: \"Mario\", surname: \"Rossi\", active: true},\n * {id: 4, name: \"Paolo\", surname: \"Bianchi\", active: false}\n * ];\n * var discard = _.compose(_.mapWith, _.skipKeys);\n * var discardNames = discard([\"name\", \"surname\"]);\n *\n * discardNames(users) // =>\n * // [\n * // {id: 1, active: false},\n * // {id: 2, active: true},\n * // {id: 3, active: true},\n * // {id: 4, active: false}\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.skip|skip}, {@link module:lamb.skipIf|skipIf}\n * @see {@link module:lamb.pick|pick}, {@link module:lamb.pickKeys|pickKeys},\n * {@link module:lamb.pickIf|pickIf}\n * @since 0.35.0\n * @param {String[]} blacklist\n * @returns {Function}\n */\n var skipKeys = _curry2(skip, true);\n\n /**\n * Using the provided function to retrieve the keys of an object, builds\n * a function expecting an object to create an array containing a list\n * of the keys in its first index and the corresponding list of values\n * in the second one.\n * @private\n * @function\n * @param {Function} getKeys\n * @returns {Function}\n */\n var _tearFrom = _curry2(function (getKeys, obj) {\n return reduce(getKeys(obj), function (result, key) {\n result[0].push(key);\n result[1].push(obj[key]);\n\n return result;\n }, [[], []]);\n });\n\n /**\n * Tears an object apart by transforming it in an array of two lists: one containing\n * its enumerable keys, the other containing the corresponding values.
\n * Although this \"tearing apart\" may sound as a rather violent process, the source\n * object will be unharmed.\n * @example\n * _.tear({a: 1, b: 2, c: 3}) // => [[\"a\", \"b\", \"c\"], [1, 2, 3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tearOwn|tearOwn}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.8.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tear = _tearFrom(enumerables);\n\n /**\n * Same as {@link module:lamb.tear|tear}, but only the own properties of the object are\n * taken into account.\n * @example Showing the difference with tear:\n * var baseFoo = Object.create({a: 1}, {b: {value: 2, enumerable: true}, z: {value: 5}});\n * var foo = Object.create(baseFoo, {\n * c: {value: 3, enumerable: true}\n * });\n *\n * _.tear(foo) // => [[\"c\", \"b\", \"a\"], [3, 2, 1]]\n * _.tearOwn(foo) // => [[\"c\"], [3]]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.tear|tear}\n * @see {@link module:lamb.make|make} for the reverse operation\n * @since 0.12.0\n * @param {Object} obj\n * @returns {Array}\n */\n var tearOwn = _tearFrom(keys);\n\n /**\n * Creates a copy of the given object having the desired key value updated by applying\n * the provided function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var toUpperCase = _.invoker(\"toUpperCase\");\n *\n * _.updateIn(user, \"name\", toUpperCase) // => {name: \"JOHN\", visits: 2}\n * _.updateIn(user, \"surname\", toUpperCase) // => {name: \"John\", visits: 2}\n *\n * @example Non-enumerable properties will be treated as non-existent:\n * var user = Object.create({name: \"John\"}, {visits: {value: 2}});\n *\n * _.updateIn(user, \"visits\", _.add(1)) // => {name: \"John\", visits: 2}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updateKey|updateKey}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {Object} source\n * @param {String} key\n * @param {Function} updater\n * @returns {Object}\n */\n function updateIn (source, key, updater) {\n return _isEnumerable(source, key)\n ? _setIn(source, key, updater(source[key]))\n : _merge(enumerables, source, {});\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updateIn|updateIn} with the provided\n * key and updater, expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setIn|setIn}; a copy of the\n * source is returned otherwise.\n * @example\n * var user = {name: \"John\", visits: 2};\n * var incrementVisits = _.updateKey(\"visits\", _.add(1));\n *\n * incrementVisits(user) // => {name: \"John\", visits: 3}\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.updateIn|updateIn}\n * @see {@link module:lamb.updatePath|updatePath}, {@link module:lamb.updatePathIn|updatePathIn}\n * @since 0.22.0\n * @param {String} key\n * @param {Function} updater\n * @returns {Function}\n */\n var updateKey = _makePartial3(updateIn);\n\n /**\n * Allows to change a nested value in a copy of the given object by applying the provided\n * function to it.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var inc = _.add(1);\n *\n * _.updatePathIn(user, \"status.visits\", inc) // => {id: 1, status: {scores: [2, 4, 6]}, visits: 1}\n *\n * @example Targeting arrays:\n * _.updatePathIn(user, \"status.scores.0\", inc) // => {id: 1, status: {scores: [3, 4, 6], visits: 0}}\n *\n * // you can use negative indexes as well\n * _.updatePathIn(user, \"status.scores.-1\", inc) // => {id: 1, status: {scores: [2, 4, 7], visits: 0}}\n *\n * @example Arrays can also be part of the path and not necessarily its target:\n * var user = {id: 1, scores: [\n * {value: 2, year: \"2000\"},\n * {value: 4, year: \"2001\"},\n * {value: 6, year: \"2002\"}\n * ]};\n *\n * var newUser = _.updatePathIn(user, \"scores.0.value\", inc);\n * // \"newUser\" holds:\n * // {id: 1, scores: [\n * // {value: 3, year: \"2000\"},\n * // {value: 4, year: \"2001\"},\n * // {value: 6, year: \"2002\"}\n * // ]}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePath|updatePath}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {Object|Array} source\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Object|Array}\n */\n function updatePathIn (source, path, updater, separator) {\n var parts = _toPathParts(path, separator);\n var pathInfo = _getPathInfo(source, parts, false);\n\n if (pathInfo.isValid) {\n return _setPathIn(source, parts, updater(pathInfo.target));\n } else {\n return Array.isArray(source) ? slice(source, 0, source.length) : _merge(enumerables, source, {});\n }\n }\n\n /**\n * Builds a partial application of {@link module:lamb.updatePathIn|updatePathIn}\n * expecting the object to act upon.
\n * This function is meant for updating existing enumerable properties, and for those it\n * will delegate the \"set action\" to {@link module:lamb.setPathIn|setPathIn}; a copy of the\n * source is returned otherwise.
\n * Like the other \"path\" functions, negative indexes can be used to access array elements, but\n * the priority will be given to existing, and enumerable, object keys.\n * @example\n * var user = {id: 1, status: {scores: [2, 4, 6], visits: 0}};\n * var incrementScores = _.updatePath(\"status.scores\", _.mapWith(_.add(1)))\n *\n * incrementScores(user) // => {id: 1, status: {scores: [3, 5, 7], visits: 0}}\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.updatePathIn|updatePathIn}\n * @see {@link module:lamb.updateIn|updateIn}, {@link module:lamb.updateKey|updateKey}\n * @since 0.24.0\n * @param {String} path\n * @param {Function} updater\n * @param {String} [separator=\".\"]\n * @returns {Function}\n */\n function updatePath (path, updater, separator) {\n return function (source) {\n return updatePathIn(source, path, updater, separator);\n };\n }\n\n /**\n * Validates an object with the given list of {@link module:lamb.checker|checker} functions.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * _.validate(user1, userCheckers) // => []\n * _.validate(user2, userCheckers) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @see {@link module:lamb.validateWith|validateWith}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Object} obj\n * @param {Function[]} checkers\n * @returns {Array>} An array of errors in the form returned by\n * {@link module:lamb.checker|checker}, or an empty array.\n */\n function validate (obj, checkers) {\n return reduce(checkers, function (errors, _checker) {\n var result = _checker(obj);\n\n result.length && errors.push(result);\n\n return errors;\n }, []);\n }\n\n /**\n * A curried version of {@link module:lamb.validate|validate} accepting a list of\n * {@link module:lamb.checker|checkers} and returning a function expecting the object to validate.\n * @example\n * var hasContent = function (s) { return s.trim().length > 0; };\n * var userCheckers = [\n * _.checker(hasContent, \"Name is required\", [\"name\"]),\n * _.checker(hasContent, \"Surname is required\", [\"surname\"]),\n * _.checker(_.isGTE(18), \"Must be at least 18 years old\", [\"age\"])\n * ];\n * var validateUser = _.validateWith(userCheckers);\n *\n * var user1 = {name: \"john\", surname: \"doe\", age: 30};\n * var user2 = {name: \"jane\", surname: \"\", age: 15};\n *\n * validateUser(user1) // => []\n * validateUser(user2) // =>\n * // [\n * // [\"Surname is required\", [\"surname\"]],\n * // [\"Must be at least 18 years old\", [\"age\"]]\n * // ]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.validate|validate}\n * @see {@link module:lamb.checker|checker}\n * @since 0.1.0\n * @param {Function[]} checkers\n * @returns {Function}\n */\n var validateWith = _curry2(validate, true);\n\n /**\n * Generates an array with the values of the enumerable properties of the given object.
\n * See also {@link module:lamb.ownValues|ownValues} to pick only from the own properties of the object.\n * @example\n * var user = {name: \"john\", surname: \"doe\", age: 30};\n *\n * _.values(user) // => [\"john\", \"doe\", 30]\n *\n * @memberof module:lamb\n * @category Object\n * @function\n * @see {@link module:lamb.ownValues|ownValues}\n * @since 0.1.0\n * @param {Object} obj\n * @returns {Array}\n */\n var values = _valuesFrom(enumerables);\n\n /**\n * A null-safe function to repeat the source string the desired amount of times.\n * @private\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function _repeat (source, times) {\n var result = \"\";\n\n for (var i = 0; i < times; i++) {\n result += source;\n }\n\n return result;\n }\n\n /**\n * Builds the prefix or suffix to be used when padding a string.\n * @private\n * @param {String} source\n * @param {String} char\n * @param {Number} len\n * @returns {String}\n */\n function _getPadding (source, char, len) {\n if (!isNil(source) && type(source) !== \"String\") {\n source = String(source);\n }\n\n return _repeat(String(char)[0] || \"\", Math.ceil(len - source.length));\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the beginning of the string.\n * @example\n * _.padLeft(\"foo\", \"-\", 0) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", -1) // => \"foo\"\n * _.padLeft(\"foo\", \"-\", 5) // => \"--foo\"\n * _.padLeft(\"foo\", \"-\", 3) // => \"foo\"\n * _.padLeft(\"foo\", \"ab\", 7) // => \"aaaafoo\"\n * _.padLeft(\"foo\", \"\", 5) // => \"foo\"\n * _.padLeft(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padRight|padRight}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padLeft (source, char, len) {\n return _getPadding(source, char, len) + source;\n }\n\n /**\n * Pads a string to the desired length with the given char starting from the end of the string.\n * @example\n * _.padRight(\"foo\", \"-\", 0) // => \"foo\"\n * _.padRight(\"foo\", \"-\", -1) // => \"foo\"\n * _.padRight(\"foo\", \"-\", 5) // => \"foo--\"\n * _.padRight(\"foo\", \"-\", 3) // => \"foo\"\n * _.padRight(\"foo\", \"ab\", 7) // => \"fooaaaa\"\n * _.padRight(\"foo\", \"\", 5) // => \"foo\"\n * _.padRight(\"\", \"-\", 5) // => \"-----\"\n *\n * @memberof module:lamb\n * @category String\n * @see {@link module:lamb.padLeft|padLeft}\n * @since 0.1.0\n * @param {String} source\n * @param {String} char - The padding char. If a string is passed only the first char is used.\n * @param {Number} len\n * @returns {String}\n */\n function padRight (source, char, len) {\n return source + _getPadding(source, char, len);\n }\n\n /**\n * Builds a new string by repeating the source string the desired amount of times.
\n * Note that unlike the current ES6 proposal for\n * [String.prototype.repeat]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat},\n * this function doesn't throw a RangeError if times is negative,\n * but returns an empty string instead.\n * @example\n * _.repeat(\"Hello\", -1) // => \"\"\n * _.repeat(\"Hello\", 1) // => \"Hello\"\n * _.repeat(\"Hello\", 3) // => \"HelloHelloHello\"\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {String} source\n * @param {Number} times\n * @returns {String}\n */\n function repeat (source, times) {\n if (isNil(source)) {\n throw _makeTypeErrorFor(source, \"string\");\n }\n\n return _repeat(source, Math.floor(times));\n }\n\n /**\n * A generic version of String.prototype.search\n * @private\n * @function\n * @param {String} s\n * @param {RegExp} pattern\n * @return {Number}\n */\n var _search = generic(String.prototype.search);\n\n /**\n * Builds a predicate expecting a string to test against the given regular expression pattern.\n * @example\n * var hasNumbersOnly = _.testWith(/^\\d+$/);\n *\n * hasNumbersOnly(\"123\") // => true\n * hasNumbersOnly(\"123 Kg\") // => false\n *\n * @memberof module:lamb\n * @category String\n * @since 0.1.0\n * @param {RegExp} pattern\n * @returns {Function}\n */\n function testWith (pattern) {\n return function (s) {\n return _search(s, pattern) !== -1;\n };\n }\n\n /**\n * Accepts a constructor and builds a predicate expecting an object,\n * which will be tested to verify whether the prototype of the constructor\n * is in its prototype chain.
\n * Wraps in a convenient way the native\n * [instanceof]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof} operator.\n * @example\n * function SomeObjA () {}\n *\n * var a = new SomeObjA();\n * var sObj = new String(\"foo\");\n * var s = \"foo\";\n *\n * _.isInstanceOf(Object)(a) // => true\n * _.isInstanceOf(SomeObjA)(a) // => true\n *\n * _.isInstanceOf(Object)(sObj) // => true\n * _.isInstanceOf(String)(sObj) // => true\n *\n * _.isInstanceOf(Object)(s) // => false\n * _.isInstanceOf(String)(s) // => false\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.isType|isType}\n * @since 0.47.0\n * @param {*} constructor\n * @returns {Function}\n */\n function isInstanceOf (constructor) {\n return function (obj) {\n return obj instanceof constructor;\n };\n }\n\n /**\n * Builds a predicate that expects a value to check against the specified type.\n * @example\n * var isString = _.isType(\"String\");\n *\n * isString(\"Hello\") // => true\n * isString(new String(\"Hi\")) // => true\n *\n * @memberof module:lamb\n * @category Type\n * @see {@link module:lamb.type|type}\n * @since 0.1.0\n * @param {String} typeName\n * @returns {Function}\n */\n function isType (typeName) {\n return function (value) {\n return type(value) === typeName;\n };\n }\n\n exports.__ = __;\n exports.adapter = adapter;\n exports.add = add;\n exports.allOf = allOf;\n exports.always = always;\n exports.anyOf = anyOf;\n exports.append = append;\n exports.appendTo = appendTo;\n exports.application = application;\n exports.apply = apply;\n exports.applyTo = applyTo;\n exports.areSVZ = areSVZ;\n exports.areSame = areSame;\n exports.aritize = aritize;\n exports.asPartial = asPartial;\n exports.binary = binary;\n exports.case = case_;\n exports.checker = checker;\n exports.clamp = clamp;\n exports.clampWithin = clampWithin;\n exports.collect = collect;\n exports.compose = compose;\n exports.condition = condition;\n exports.contains = contains;\n exports.count = count;\n exports.countBy = countBy;\n exports.curry = curry;\n exports.curryRight = curryRight;\n exports.curryable = curryable;\n exports.curryableRight = curryableRight;\n exports.debounce = debounce;\n exports.deduct = deduct;\n exports.difference = difference;\n exports.divide = divide;\n exports.divideBy = divideBy;\n exports.drop = drop;\n exports.dropFrom = dropFrom;\n exports.dropLastWhile = dropLastWhile;\n exports.dropWhile = dropWhile;\n exports.enumerables = enumerables;\n exports.every = every;\n exports.everyIn = everyIn;\n exports.filter = filter;\n exports.filterWith = filterWith;\n exports.find = find;\n exports.findIndex = findIndex;\n exports.findIndexWhere = findIndexWhere;\n exports.findLast = findLast;\n exports.findLastIndex = findLastIndex;\n exports.findLastIndexWhere = findLastIndexWhere;\n exports.findLastWhere = findLastWhere;\n exports.findWhere = findWhere;\n exports.flatMap = flatMap;\n exports.flatMapWith = flatMapWith;\n exports.flatten = flatten;\n exports.flip = flip;\n exports.forEach = forEach;\n exports.fromPairs = fromPairs;\n exports.generate = generate;\n exports.generic = generic;\n exports.getArgAt = getArgAt;\n exports.getAt = getAt;\n exports.getIn = getIn;\n exports.getIndex = getIndex;\n exports.getKey = getKey;\n exports.getPath = getPath;\n exports.getPathIn = getPathIn;\n exports.group = group;\n exports.groupBy = groupBy;\n exports.gt = gt;\n exports.gte = gte;\n exports.has = has;\n exports.hasKey = hasKey;\n exports.hasKeyValue = hasKeyValue;\n exports.hasOwn = hasOwn;\n exports.hasOwnKey = hasOwnKey;\n exports.hasPathValue = hasPathValue;\n exports.head = head;\n exports.identity = identity;\n exports.index = index;\n exports.indexBy = indexBy;\n exports.init = init;\n exports.insert = insert;\n exports.insertAt = insertAt;\n exports.intersection = intersection;\n exports.invoker = invoker;\n exports.invokerOn = invokerOn;\n exports.is = is;\n exports.isFinite = isFinite_;\n exports.isGT = isGT;\n exports.isGTE = isGTE;\n exports.isIn = isIn;\n exports.isInstanceOf = isInstanceOf;\n exports.isInteger = isInteger;\n exports.isLT = isLT;\n exports.isLTE = isLTE;\n exports.isNil = isNil;\n exports.isNull = isNull;\n exports.isSVZ = isSVZ;\n exports.isSafeInteger = isSafeInteger;\n exports.isType = isType;\n exports.isUndefined = isUndefined;\n exports.join = join;\n exports.joinWith = joinWith;\n exports.keySatisfies = keySatisfies;\n exports.keys = keys;\n exports.last = last;\n exports.list = list;\n exports.lt = lt;\n exports.lte = lte;\n exports.make = make;\n exports.map = map;\n exports.mapArgs = mapArgs;\n exports.mapValues = mapValues;\n exports.mapValuesWith = mapValuesWith;\n exports.mapWith = mapWith;\n exports.merge = merge;\n exports.mergeOwn = mergeOwn;\n exports.modulo = modulo;\n exports.multiply = multiply;\n exports.multiplyBy = multiplyBy;\n exports.not = not;\n exports.ownPairs = ownPairs;\n exports.ownValues = ownValues;\n exports.padLeft = padLeft;\n exports.padRight = padRight;\n exports.pairs = pairs;\n exports.partial = partial;\n exports.partialRight = partialRight;\n exports.partition = partition;\n exports.partitionWith = partitionWith;\n exports.pathExists = pathExists;\n exports.pathExistsIn = pathExistsIn;\n exports.pathSatisfies = pathSatisfies;\n exports.pick = pick;\n exports.pickIf = pickIf;\n exports.pickKeys = pickKeys;\n exports.pipe = pipe;\n exports.pluck = pluck;\n exports.pluckKey = pluckKey;\n exports.pull = pull;\n exports.pullFrom = pullFrom;\n exports.randomInt = randomInt;\n exports.range = range;\n exports.reduce = reduce;\n exports.reduceRight = reduceRight;\n exports.reduceRightWith = reduceRightWith;\n exports.reduceWith = reduceWith;\n exports.remainder = remainder;\n exports.rename = rename;\n exports.renameKeys = renameKeys;\n exports.renameWith = renameWith;\n exports.repeat = repeat;\n exports.reverse = reverse;\n exports.rotate = rotate;\n exports.rotateBy = rotateBy;\n exports.setAt = setAt;\n exports.setIn = setIn;\n exports.setIndex = setIndex;\n exports.setKey = setKey;\n exports.setPath = setPath;\n exports.setPathIn = setPathIn;\n exports.shallowFlatten = shallowFlatten;\n exports.skip = skip;\n exports.skipIf = skipIf;\n exports.skipKeys = skipKeys;\n exports.slice = slice;\n exports.sliceAt = sliceAt;\n exports.some = some;\n exports.someIn = someIn;\n exports.sort = sort;\n exports.sortWith = sortWith;\n exports.sortedInsert = sortedInsert;\n exports.sorter = sorter;\n exports.sorterDesc = sorterDesc;\n exports.subtract = subtract;\n exports.sum = sum;\n exports.tail = tail;\n exports.take = take;\n exports.takeFrom = takeFrom;\n exports.takeLastWhile = takeLastWhile;\n exports.takeWhile = takeWhile;\n exports.tapArgs = tapArgs;\n exports.tear = tear;\n exports.tearOwn = tearOwn;\n exports.testWith = testWith;\n exports.throttle = throttle;\n exports.transpose = transpose;\n exports.type = type;\n exports.unary = unary;\n exports.union = union;\n exports.unionBy = unionBy;\n exports.uniques = uniques;\n exports.uniquesBy = uniquesBy;\n exports.unless = unless;\n exports.updateAt = updateAt;\n exports.updateIn = updateIn;\n exports.updateIndex = updateIndex;\n exports.updateKey = updateKey;\n exports.updatePath = updatePath;\n exports.updatePathIn = updatePathIn;\n exports.validate = validate;\n exports.validateWith = validateWith;\n exports.values = values;\n exports.when = when;\n exports.zip = zip;\n exports.zipWithIndex = zipWithIndex;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n}));\n"]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bd988ee..0b81757 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamb", - "version": "0.58.0-alpha.9", + "version": "0.58.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fad21bf..7effc7b 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,7 @@ "node": ">=4.0.0" }, "files": [ - "dist/lamb.js", - "dist/lamb.min.js", - "dist/lamb.min.js.map", - "src/*.js", - "src/**/!(__tests__)/*.js" + "dist" ], "homepage": "https://ascartabelli.github.io/lamb/", "keywords": [ @@ -51,7 +47,7 @@ "unpkg": "dist/lamb.min.js", "sideEffects": false, "tonicExample": "var _ = require('lamb');", - "version": "0.58.0-alpha.9", + "version": "0.58.0", "devDependencies": { "@babel/preset-env": "^7.4.5", "coveralls": "^3.0.4", diff --git a/src/array/findLastWhere.js b/src/array/findLastWhere.js index bae4ad6..5370713 100644 --- a/src/array/findLastWhere.js +++ b/src/array/findLastWhere.js @@ -2,8 +2,8 @@ import _curry2 from "../privates/_curry2"; import findLast from "./findLast"; /** - * A curried version of {@link module:lamb.findLast|findLast} expecting the array-like object - * to search. + * A curried version of {@link module:lamb.findLast|findLast} that uses the given + * predicate to build a function expecting the array-like object to search. * @example * var isEven = function (n) { return n % 2 === 0; }; * var findEven = _.findLastWhere(isEven); diff --git a/src/array/findWhere.js b/src/array/findWhere.js index 68fef05..7b40d53 100644 --- a/src/array/findWhere.js +++ b/src/array/findWhere.js @@ -2,8 +2,8 @@ import _curry2 from "../privates/_curry2"; import find from "./find"; /** - * A curried version of {@link module:lamb.find|find} expecting the array-like object - * to search. + * A curried version of {@link module:lamb.find|find} that uses the given + * predicate to build a function expecting the array-like object to search. * @example * var isEven = function (n) { return n % 2 === 0; }; * var findEven = _.findWhere(isEven); diff --git a/src/logic/adapter.js b/src/logic/adapter.js index 798ff2a..3631961 100644 --- a/src/logic/adapter.js +++ b/src/logic/adapter.js @@ -9,7 +9,7 @@ import _makeTypeErrorFor from "../privates/_makeTypeErrorFor"; * to mimic conditional logic or pattern matching, and also to build polymorphic functions. * @example * var isEven = function (n) { return n % 2 === 0; }; - * var filterString = _.compose(_.invoker("join", [""]), _.filter); + * var filterString = _.compose(_.joinWith(""), _.filter); * var filterAdapter = _.adapter([ * _.invoker("filter"), * _.case(_.isType("String"), filterString)