From aefbdbb6d558fe46b16dd1ac85101da3b71e66e0 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 7 Feb 2016 22:48:19 -0800 Subject: [PATCH 01/79] Increment package version to enable ci tests. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5807ecf026..a4c047ea33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "4.3.0", + "version": "4.3.1-pre", "main": "lodash.js", "private": true, "devDependencies": { From 285b667c3eb115b782c874dd5d1d0538d3cc3a65 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 8 Feb 2016 22:23:08 -0800 Subject: [PATCH 02/79] Update "Why Lodash" section of readme. [ci skip] --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 77bcf52aba..03591fa863 100644 --- a/README.md +++ b/README.md @@ -9,10 +9,10 @@ $ lodash -o ./dist/lodash.js $ lodash core -o ./dist/lodash.core.js ``` -## What is Lodash +## Why Lodash? Lodash makes JavaScript easier by taking the hassle out of working with arrays,
-numbers, objects, strings, etc. Lodash’s modular methods can be used for: +numbers, objects, strings, etc. Lodash’s modular methods are great for: * Iterating arrays, objects, & strings * Manipulating & testing values From e36f7e7161112b2508d864f107dba7d9d2b4aa5c Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 8 Feb 2016 11:41:39 -0800 Subject: [PATCH 03/79] Enable testing `fp/convert` in the browser. --- test/test-fp.js | 292 ++++++++++++++++++++---------------------------- 1 file changed, 124 insertions(+), 168 deletions(-) diff --git a/test/test-fp.js b/test/test-fp.js index 9449bd0b0e..3c926acce0 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -44,10 +44,21 @@ QUnitExtras.runInContext(root); } - var convert = root.fp || (function() { - var baseConvert = load('../fp/_baseConvert.js'); + var convert = (function() { + var baseConvert = root.fp || load('../fp/_baseConvert.js'); + if (!root.fp) { + return function(name, func, options) { + return baseConvert(_, name, func, options); + }; + } return function(name, func, options) { - return baseConvert(_, name, func, options); + if (typeof func != 'function') { + func = name; + name = undefined; + } + return name === undefined + ? baseConvert(func, options) + : baseConvert(_.runInContext(), options)[name]; }; }()); @@ -82,90 +93,70 @@ QUnit.test('should accept an `options` argument', function(assert) { assert.expect(3); - if (!document) { - var remove = convert('remove', _.remove, { - 'cap': false, - 'curry': false, - 'fixed': false, - 'immutable': false, - 'rearg': false - }); + var array = [1, 2, 3, 4]; - var array = [1, 2, 3, 4]; + var remove = convert('remove', _.remove, { + 'cap': false, + 'curry': false, + 'fixed': false, + 'immutable': false, + 'rearg': false + }); - var actual = remove(array, function(n) { - return n % 2 == 0; - }); + var actual = remove(array, function(n, index) { + return index % 2 == 0; + }); - assert.deepEqual(array, [1, 3]); - assert.deepEqual(actual, [2, 4]); - assert.deepEqual(remove(), []); - } - else { - skipTest(assert, 3); - } + assert.deepEqual(array, [2, 4]); + assert.deepEqual(actual, [1, 3]); + assert.deepEqual(remove(), []); }); QUnit.test('should respect the `cap` option', function(assert) { assert.expect(1); - if (!document) { - var iteratee = convert('iteratee', _.iteratee, { - 'cap': false - }); + var iteratee = convert('iteratee', _.iteratee, { + 'cap': false + }); - var func = iteratee(function(a, b, c) { - return [a, b, c]; - }, 3); + var func = iteratee(function(a, b, c) { + return [a, b, c]; + }, 3); - assert.deepEqual(func(1, 2, 3), [1, 2, 3]); - } - else { - skipTest(assert); - } + assert.deepEqual(func(1, 2, 3), [1, 2, 3]); }); QUnit.test('should respect the `rearg` option', function(assert) { assert.expect(1); - if (!document) { - var add = convert('add', _.add, { - 'rearg': true - }); + var add = convert('add', _.add, { + 'rearg': true + }); - assert.strictEqual(add('2')('1'), '12'); - } - else { - skipTest(assert); - } + assert.strictEqual(add('2')('1'), '12'); }); QUnit.test('should use `options` in `runInContext`', function(assert) { assert.expect(3); - if (!document) { - var runInContext = convert('runInContext', _.runInContext, { - 'cap': false, - 'curry': false, - 'fixed': false, - 'immutable': false, - 'rearg': false - }); + var runInContext = convert('runInContext', _.runInContext, { + 'cap': false, + 'curry': false, + 'fixed': false, + 'immutable': false, + 'rearg': false + }); - var array = [1, 2, 3, 4], - lodash = runInContext(); + var array = [1, 2, 3, 4], + lodash = runInContext(); - var actual = lodash.remove(array, function(n) { - return n % 2 == 0; - }); + var actual = lodash.remove(array, function(n) { + return n % 2 == 0; + }); - assert.deepEqual(array, [1, 3]); - assert.deepEqual(actual, [2, 4]); - assert.deepEqual(lodash.remove(), []); - } - else { - skipTest(assert, 3); - } + assert.deepEqual(array, [1, 3]); + assert.deepEqual(actual, [2, 4]); + assert.deepEqual(lodash.remove(), []); }); }()); @@ -356,81 +347,71 @@ QUnit.test('should provide the correct `iteratee` arguments', function(assert) { assert.expect(4); - if (!document) { - var args, - array = [1, 2, 3], - object = { 'a': 1, 'b': 2 }, - isFIFO = _.keys(object)[0] == 'a', - map = convert('map', _.map), - reduce = convert('reduce', _.reduce); + var args, + array = [1, 2, 3], + object = { 'a': 1, 'b': 2 }, + isFIFO = _.keys(object)[0] == 'a', + map = convert('map', _.map), + reduce = convert('reduce', _.reduce); - map(function() { - args || (args = slice.call(arguments)); - })(array); + map(function() { + args || (args = slice.call(arguments)); + })(array); - assert.deepEqual(args, [1]); + assert.deepEqual(args, [1]); - args = undefined; - map(function() { - args || (args = slice.call(arguments)); - })(object); + args = undefined; + map(function() { + args || (args = slice.call(arguments)); + })(object); - assert.deepEqual(args, isFIFO ? [1] : [2]); + assert.deepEqual(args, isFIFO ? [1] : [2]); - args = undefined; - reduce(function() { - args || (args = slice.call(arguments)); - })(0, array); + args = undefined; + reduce(function() { + args || (args = slice.call(arguments)); + })(0, array); - assert.deepEqual(args, [0, 1]); + assert.deepEqual(args, [0, 1]); - args = undefined; - reduce(function() { - args || (args = slice.call(arguments)); - })(0, object); + args = undefined; + reduce(function() { + args || (args = slice.call(arguments)); + })(0, object); - assert.deepEqual(args, isFIFO ? [0, 1] : [0, 2]); - } - else { - skipTest(assert, 4); - } + assert.deepEqual(args, isFIFO ? [0, 1] : [0, 2]); }); QUnit.test('should not support shortcut fusion', function(assert) { assert.expect(3); - if (!document) { - var array = fp.range(0, LARGE_ARRAY_SIZE), - filterCount = 0, - mapCount = 0; + var array = fp.range(0, LARGE_ARRAY_SIZE), + filterCount = 0, + mapCount = 0; - var iteratee = function(value) { - mapCount++; - return value * value; - }; + var iteratee = function(value) { + mapCount++; + return value * value; + }; - var predicate = function(value) { - filterCount++; - return value % 2 == 0; - }; + var predicate = function(value) { + filterCount++; + return value % 2 == 0; + }; - var map1 = convert('map', _.map), - filter1 = convert('filter', _.filter), - take1 = convert('take', _.take); + var map1 = convert('map', _.map), + filter1 = convert('filter', _.filter), + take1 = convert('take', _.take); - var filter2 = filter1(predicate), - map2 = map1(iteratee), - take2 = take1(2); + var filter2 = filter1(predicate), + map2 = map1(iteratee), + take2 = take1(2); - var combined = fp.flow(map2, filter2, fp.compact, take2); + var combined = fp.flow(map2, filter2, fp.compact, take2); - assert.deepEqual(combined(array), [4, 16]); - assert.strictEqual(filterCount, 200, 'filterCount'); - assert.strictEqual(mapCount, 200, 'mapCount'); - } - else { - skipTest(assert, 3); - } + assert.deepEqual(combined(array), [4, 16]); + assert.strictEqual(filterCount, 200, 'filterCount'); + assert.strictEqual(mapCount, 200, 'mapCount'); }); }()); @@ -757,17 +738,12 @@ var object = { 'a': 1 }; - if (!document) { - var extend = convert('extend', _.extend), - value = _.clone(object), - actual = extend(value, new Foo); + var extend = convert('extend', _.extend), + value = _.clone(object), + actual = extend(value, new Foo); - assert.deepEqual(value, object); - assert.deepEqual(actual, { 'a': 1, 'b': 2 }); - } - else { - skipTest(assert, 2); - } + assert.deepEqual(value, object); + assert.deepEqual(actual, { 'a': 1, 'b': 2 }); }); }()); @@ -883,15 +859,10 @@ QUnit.test('should convert by name', function(assert) { assert.expect(1); - if (!document) { - var iteratee = convert('iteratee', _.iteratee), - func = iteratee(function(a, b, c) { return [a, b, c]; }, undefined, 3); + var iteratee = convert('iteratee', _.iteratee), + func = iteratee(function(a, b, c) { return [a, b, c]; }, undefined, 3); - assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]); - } - else { - skipTest(assert); - } + assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]); }); }()); @@ -1012,22 +983,17 @@ QUnit.test('should convert by name', function(assert) { assert.expect(3); - if (!document) { - var object = { 'mixin': convert('mixin', _.mixin) }; + var object = { 'mixin': convert('mixin', _.mixin) }; - function Foo() {} - Foo.mixin = object.mixin; - Foo.mixin(source); + function Foo() {} + Foo.mixin = object.mixin; + Foo.mixin(source); - assert.strictEqual(typeof Foo.a, 'function'); - assert.notOk('a' in Foo.prototype); + assert.strictEqual(typeof Foo.a, 'function'); + assert.notOk('a' in Foo.prototype); - object.mixin(source); - assert.strictEqual(typeof object.a, 'function'); - } - else { - skipTest(assert, 3); - } + object.mixin(source); + assert.strictEqual(typeof object.a, 'function'); }); }()); @@ -1054,19 +1020,14 @@ QUnit.test('`_.' + methodName + '` should convert by name', function(assert) { assert.expect(1); - if (!document) { - var expected = isPartial ? [1, 2, 3] : [0, 1, 2], - par = convert(methodName, _[methodName]); + var expected = isPartial ? [1, 2, 3] : [0, 1, 2], + par = convert(methodName, _[methodName]); - var actual = par(function(a, b, c) { - return [a, b, c]; - })([1, 2])(isPartial ? 3 : 0); + var actual = par(function(a, b, c) { + return [a, b, c]; + })([1, 2])(isPartial ? 3 : 0); - assert.deepEqual(actual, expected); - } - else { - skipTest(assert); - } + assert.deepEqual(actual, expected); }); }); @@ -1156,13 +1117,8 @@ QUnit.test('should convert by name', function(assert) { assert.expect(1); - if (!document) { - var runInContext = convert('runInContext', _.runInContext); - assert.strictEqual(typeof runInContext({}).curryN, 'function'); - } - else { - skipTest(assert); - } + var runInContext = convert('runInContext', _.runInContext); + assert.strictEqual(typeof runInContext({}).curryN, 'function'); }); }()); From d8bf62995b512e3e18e0ef373e0943999ef42d85 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 8 Feb 2016 22:22:42 -0800 Subject: [PATCH 04/79] Ensure fp options works when applied individually. --- fp/_baseConvert.js | 35 +++++++++++++++++++++++++---------- test/test-fp.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index 76cc02ce86..cf742defed 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -89,7 +89,19 @@ function baseConvert(util, name, func, options) { }; var immutWrap = function(func, cloner) { - return overArg(func, cloner, true); + return function() { + var length = arguments.length; + if (!length) { + return result; + } + var args = Array(length); + while (length--) { + args[length] = arguments[length]; + } + var result = args[0] = cloner(args[0]); + func.apply(undefined, args); + return result; + }; }; var iterateeAry = function(func, n) { @@ -107,15 +119,17 @@ function baseConvert(util, name, func, options) { var overArg = function(func, iteratee, retArg) { return function() { - var length = arguments.length, - args = Array(length); - + var length = arguments.length; + if (!length) { + return func(); + } + var args = Array(length); while (length--) { args[length] = arguments[length]; } - args[0] = iteratee(args[0]); - var result = func.apply(undefined, args); - return retArg ? args[0] : result; + var index = config.rearg ? 0 : (length - 1); + args[index] = iteratee(args[index]); + return func.apply(undefined, args); }; }; @@ -197,10 +211,11 @@ function baseConvert(util, name, func, options) { reargIndexes = mapping.iterateeRearg[name], spreadStart = mapping.methodSpread[name]; + result = wrapped; if (config.fixed) { result = spreadStart === undefined - ? ary(wrapped, cap) - : spread(wrapped, spreadStart); + ? ary(result, cap) + : spread(result, spreadStart); } if (config.rearg && cap > 1 && (forceRearg || !mapping.skipRearg[name])) { result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]); @@ -221,7 +236,7 @@ function baseConvert(util, name, func, options) { return !result; }); - result || (result = func); + result || (result = wrapped); if (mapping.placeholder[name]) { func.placeholder = result.placeholder = placeholder; } diff --git a/test/test-fp.js b/test/test-fp.js index 3c926acce0..7d30080454 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -112,6 +112,41 @@ assert.deepEqual(remove(), []); }); + QUnit.test('should accept a variety of options', function(assert) { + assert.expect(8); + + var array = [1, 2, 3, 4], + predicate = function(n) { return n % 2 == 0; }, + value = _.clone(array), + remove = convert('remove', _.remove, { 'cap': false }), + actual = remove(function(n, index) { return index % 2 == 0; })(value); + + assert.deepEqual(value, [1, 2, 3, 4]); + assert.deepEqual(actual, [2, 4]); + + remove = convert('remove', _.remove, { 'curry': false }); + actual = remove(predicate); + + assert.deepEqual(actual, []); + + var trim = convert('trim', _.trim, { 'fixed': false }); + assert.strictEqual(trim('_-abc-_', '_-'), 'abc'); + + value = _.clone(array); + remove = convert('remove', _.remove, { 'immutable': false }); + actual = remove(predicate)(value); + + assert.deepEqual(value, [1, 3]); + assert.deepEqual(actual, [2, 4]); + + value = _.clone(array); + remove = convert('remove', _.remove, { 'rearg': false }); + actual = remove(value, predicate); + + assert.deepEqual(value, [1, 2, 3, 4]); + assert.deepEqual(actual, [1, 3]); + }); + QUnit.test('should respect the `cap` option', function(assert) { assert.expect(1); From 5fe4a1b05d65a44f9678fbe509f94004aecc00e1 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 8 Feb 2016 22:48:24 -0800 Subject: [PATCH 05/79] Add fp placeholder test for converted `partial`. --- test/test-fp.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/test-fp.js b/test/test-fp.js index 7d30080454..654652928f 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -1053,16 +1053,23 @@ }); QUnit.test('`_.' + methodName + '` should convert by name', function(assert) { - assert.expect(1); + assert.expect(2); var expected = isPartial ? [1, 2, 3] : [0, 1, 2], - par = convert(methodName, _[methodName]); + par = convert(methodName, _[methodName]), + ph = par.placeholder; var actual = par(function(a, b, c) { return [a, b, c]; })([1, 2])(isPartial ? 3 : 0); assert.deepEqual(actual, expected); + + actual = par(function(a, b, c) { + return [a, b, c]; + })([ph, 2])(isPartial ? 1 : 0, isPartial ? 3 : 1); + + assert.deepEqual(actual, expected); }); }); From 495c890aacb2fa856b7a3bf39cca2ddbcabb77e9 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 9 Feb 2016 00:29:26 -0800 Subject: [PATCH 06/79] Add bizarro test for `_.isBuffer`. --- test/index.html | 16 ++++++++-------- test/test.js | 31 ++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/test/index.html b/test/index.html index 26ad54d9fa..8de250eb1f 100644 --- a/test/index.html +++ b/test/index.html @@ -82,6 +82,12 @@ funcProto._method = noop; // Set bad shims. + setProperty(Object, '_create', Object.create); + setProperty(Object, 'create', noop); + + setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols); + setProperty(Object, 'getOwnPropertySymbols', undefined); + setProperty(objectProto, '_propertyIsEnumerable', propertyIsEnumerable); setProperty(objectProto, 'propertyIsEnumerable', function(key) { return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key); @@ -103,12 +109,6 @@ setProperty(Map, 'toString', createToString('Map')); } - setProperty(Object, '_create', Object.create); - setProperty(Object, 'create', noop); - - setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols); - setProperty(Object, 'getOwnPropertySymbols', undefined); - setProperty(window, '_Set', window.Set); setProperty(window, 'Set', noop); @@ -131,6 +131,8 @@ var funcProto = Function.prototype, objectProto = Object.prototype; + setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable); + if (Object._create) { Object.create = Object._create; } else { @@ -159,8 +161,6 @@ } else { setProperty(window, 'WeakMap', undefined); } - setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable); - setProperty(window, '_Map', undefined); setProperty(window, '_Set', undefined); setProperty(window, '_Symbol', undefined); diff --git a/test/test.js b/test/test.js index d5979338eb..a948846502 100644 --- a/test/test.js +++ b/test/test.js @@ -452,6 +452,11 @@ funcProto._method = noop; // Set bad shims. + setProperty(Object, 'create', noop); + + var _getOwnPropertySymbols = Object.getOwnPropertySymbols; + setProperty(Object, 'getOwnPropertySymbols', undefined); + var _propertyIsEnumerable = objectProto.propertyIsEnumerable; setProperty(objectProto, 'propertyIsEnumerable', function(key) { return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key); @@ -472,11 +477,7 @@ setProperty(root.Map, 'toString', createToString('Map')); } - setProperty(Object, 'create', noop); - - var _getOwnPropertySymbols = Object.getOwnPropertySymbols; - setProperty(Object, 'getOwnPropertySymbols', undefined); - + setProperty(root, 'Buffer', undefined); setProperty(root, 'Set', noop); setProperty(root, 'Symbol', undefined); setProperty(root, 'WeakMap', noop); @@ -492,6 +493,10 @@ root._ = oldDash; // Restore built-in methods. + setProperty(Object, 'create', create); + setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); + setProperty(root, 'Buffer', Buffer); + if (_getOwnPropertySymbols) { Object.getOwnPropertySymbols = _getOwnPropertySymbols; } else { @@ -517,9 +522,6 @@ } else { delete root.WeakMap; } - setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); - setProperty(Object, 'create', create); - delete root.WinRTError; delete funcProto._method; }()); @@ -723,7 +725,7 @@ } }); - QUnit.test('should avoid overwritten native methods', function(assert) { + QUnit.test('should avoid non-native built-ins', function(assert) { assert.expect(6); function message(lodashMethod, nativeMethod) { @@ -8111,6 +8113,17 @@ assert.strictEqual(_.isBuffer('a'), false); assert.strictEqual(_.isBuffer(symbol), false); }); + + QUnit.test('should return `false` if `Buffer` is not defined', function(assert) { + assert.expect(1); + + if (Buffer && lodashBizarro) { + assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false); + } + else { + skipTest(assert); + } + }); }(1, 2, 3)); /*--------------------------------------------------------------------------*/ From e5bc6a03159df493a7602f64810951f5512c37cb Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 9 Feb 2016 01:47:24 -0800 Subject: [PATCH 07/79] Fix bizarro buffer test in Node v0.12. --- test/test.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index a948846502..2b0d5e854d 100644 --- a/test/test.js +++ b/test/test.js @@ -477,7 +477,22 @@ setProperty(root.Map, 'toString', createToString('Map')); } - setProperty(root, 'Buffer', undefined); + defineProperty(root, 'Buffer', (function() { + var count = 0, + limit = /^0\.12\.\d+$/.test(process.versions.node) ? 2 : 0; + + return { + 'configurable': true, + 'enumerable': true, + 'get': function() { + if (++count <= limit) { + return Buffer; + } + setProperty(root, 'Buffer', undefined); + } + }; + }())); + setProperty(root, 'Set', noop); setProperty(root, 'Symbol', undefined); setProperty(root, 'WeakMap', noop); From 5cd7208ef30d5627b5c55f0a235496a5b8a4431e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 9 Feb 2016 08:21:35 -0800 Subject: [PATCH 08/79] Fix test fail in phantomjs. --- test/test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 2b0d5e854d..5d3cea8d9e 100644 --- a/test/test.js +++ b/test/test.js @@ -41,8 +41,9 @@ /** Method and object shortcuts. */ var phantom = root.phantom, + process = root.process, amd = root.define && define.amd, - argv = root.process && process.argv, + argv = process && process.argv, defineProperty = Object.defineProperty, document = !phantom && root.document, body = root.document && root.document.body, @@ -479,7 +480,8 @@ } defineProperty(root, 'Buffer', (function() { var count = 0, - limit = /^0\.12\.\d+$/.test(process.versions.node) ? 2 : 0; + version = lodashStable.get(process, 'versions.node'), + limit = /^0\.12\b/.test(version) ? 2 : 0; return { 'configurable': true, From fbfa578c1105deff14ce76a8b9d0286d98b8beca Mon Sep 17 00:00:00 2001 From: Benjamin Tan Date: Sun, 31 Jan 2016 21:50:43 +0800 Subject: [PATCH 09/79] Write fp docs to a different file. --- lib/doc/build.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/doc/build.js b/lib/doc/build.js index e4057260ef..92b72dff5f 100644 --- a/lib/doc/build.js +++ b/lib/doc/build.js @@ -7,7 +7,8 @@ var _ = require('lodash'), var basePath = path.join(__dirname, '..', '..'), docPath = path.join(basePath, 'doc'), - readmePath = path.join(docPath, 'README.md'); + readmePath = path.join(docPath, 'README.md'), + fpReadmePath = path.join(docPath, 'fp.md'); var pkg = require('../../package.json'), version = pkg.version; @@ -47,9 +48,10 @@ function onComplete(error) { function build(type) { var options = _.defaults({}, config.base, config[type]), - markdown = docdown(options); + markdown = docdown(options), + filePath = fpFlag ? fpReadmePath : readmePath; - fs.writeFile(readmePath, postprocess(markdown), onComplete); + fs.writeFile(filePath, postprocess(markdown), onComplete); } build(_.last(process.argv)); From 66d6e226a97d8ab019da6f1514332f79e7d6af66 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Fri, 29 Jan 2016 00:09:27 +0100 Subject: [PATCH 10/79] Add scripts to generate the docs for lodash/fp. --- lib/doc/apply-fp-mapping.js | 122 ++++++++++++++++++++++++++++++++++++ lib/doc/build.js | 10 ++- package.json | 3 + 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 lib/doc/apply-fp-mapping.js diff --git a/lib/doc/apply-fp-mapping.js b/lib/doc/apply-fp-mapping.js new file mode 100644 index 0000000000..1f26088cef --- /dev/null +++ b/lib/doc/apply-fp-mapping.js @@ -0,0 +1,122 @@ +var _ = require('lodash'), + j = require('jscodeshift'), + Entry = require('docdown/lib/entry'); + +var baseGetParams = Entry.prototype.getParams; + +// Function copied from docdown/lib/entry that is not exported. +function getMultilineValue(string, tagName) { + var prelude = tagName == 'description' ? '^ */\\*\\*(?: *\\n *\\* *)?' : ('^ *\\*[\\t ]*@' + _.escapeRegExp(tagName) + '\\b'), + postlude = '(?=\\*\\s+\\@[a-z]|\\*/)', + result = _.result(RegExp(prelude + '([\\s\\S]*?)' + postlude, 'gm').exec(string), 1, ''); + + return _.trim(result.replace(RegExp('(?:^|\\n)[\\t ]*\\*[\\t ]' + (tagName == 'example' ? '?' : '*'), 'g'), '\n')); +} + +/** + * Extracts the entry's `name` data. + * Sub-part of Entry.prototype.getCall() that fetches the name. Using `Entry.prototype.getCall()` + * makes a call to getParams(), which itself call getBaseName --> infinite recursion. + * + * @param {Object} entry Entry whose name to extract. + * @returns {string} The entry's `name` data. + */ +function getBaseName(entry) { + var result = /\*\/\s*(?:function\s+([^(]*)|(.*?)(?=[:=,]))/.exec(entry); + if (result) { + result = (result[1] || result[2]).split('.').pop(); + result = _.trim(_.trim(result), "'").split('var ').pop(); + result = _.trim(result); + } + // Get the function name. + return _.result(/\*[\t ]*@name\s+(.+)/.exec(entry), 1, result || ''); +} + +/** + * Reorders `params` for a given function definition/call. + * + * @param {Object} mapping Mapping object that defines if and how the `params` will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {*[]} params Parameters/arguments to reorder. + * @returns {*[]} Reordered parameters/arguments. + */ +function reorderParams(mapping, name, params) { + // Check if reordering is needed. + if (!mapping || mapping.skipRearg[name]) { + return params; + } + var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[params.length]; + if (!reargOrder) { + return params; + } + // Reorder params. + var newParams = []; + reargOrder.forEach(function(newPosition, index) { + newParams[newPosition] = params[index]; + }); + return newParams; +} + +/** + * Returns a function that extracts the entry's `param` data, reordered according to `mapping`. + * + * @param {Object} mapping Mapping object that defines if and how the `params` will be reordered. + * @returns {Function} Function that returns the entry's `param` data. + */ +function getReorderedParams(mapping) { + return function(index) { + if (!this._params) { + // Call baseGetParams in order to compute `this._params`. + baseGetParams.call(this); + // Reorder params according to the `mapping`. + this._params = reorderParams(mapping, getBaseName(this.entry), this._params); + } + return baseGetParams.call(this, index); + }; +} + +/** + * Updates a code sample so that the arguments in the call are reordered according to `mapping`. + * + * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {string} codeSample Code sample to update. + * @returns {string} Updated code sample. + */ +function reorderParamsInExample(mapping, codeSample) { + return j(codeSample) + .find(j.CallExpression, { callee: { object: {name: '_' }}}) + .replaceWith(function(callExpr) { + var value = callExpr.value; + return j.callExpression( + value.callee, + reorderParams(mapping, value.callee.property.name, value.arguments) + ); + }) + .toSource(); +} + +/** + * Returns a function that extracts the entry's `example` data, + * where function call arguments are reordered according to `mapping`. + * + * @param {Object} mapping Mapping object that defines if and how the `params` will be reordered. + * @returns {Function} Function that returns the entry's `example` data. + */ +function getReorderedExample(mapping) { + return function() { + var result = getMultilineValue(this.entry, 'example'); + if (!result) { + return result; + } + var resultReordered = reorderParamsInExample(mapping, result); + return '```' + this.lang + '\n' + resultReordered + '\n```'; + }; +} + +/** + * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`. + */ +module.exports = function applyFPMapping(mapping) { + Entry.prototype.getParams = getReorderedParams(mapping); + Entry.prototype.getExample = getReorderedExample(mapping); +}; diff --git a/lib/doc/build.js b/lib/doc/build.js index 92b72dff5f..1ca1e9611f 100644 --- a/lib/doc/build.js +++ b/lib/doc/build.js @@ -5,6 +5,9 @@ var _ = require('lodash'), fs = require('fs-extra'), path = require('path'); +var mapping = require('../../fp/_mapping'), + applyFPMapping = require('./apply-fp-mapping'); + var basePath = path.join(__dirname, '..', '..'), docPath = path.join(basePath, 'doc'), readmePath = path.join(docPath, 'README.md'), @@ -46,7 +49,10 @@ function onComplete(error) { } } -function build(type) { +function build(fpFlag, type) { + if (fpFlag) { + applyFPMapping(mapping); + } var options = _.defaults({}, config.base, config[type]), markdown = docdown(options), filePath = fpFlag ? fpReadmePath : readmePath; @@ -54,4 +60,4 @@ function build(type) { fs.writeFile(filePath, postprocess(markdown), onComplete); } -build(_.last(process.argv)); +build(_.includes(process.argv, '--fp'), _.last(process.argv)); diff --git a/package.json b/package.json index a4c047ea33..40433ada86 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "glob": "^6.0.4", "istanbul": "0.4.2", "jquery": "^2.2.0", + "jscodeshift": "^0.3.13", "jscs": "^2.9.0", "lodash": "^3.10.1", "platform": "^1.3.1", @@ -35,6 +36,8 @@ "build:main": "node lib/main/build-dist.js", "build:main-modules": "node lib/main/build-modules.js", "doc": "node lib/doc/build github", + "doc:fp": "node lib/doc/build --fp github", + "doc:fp:site": "node lib/doc/build --fp site", "doc:site": "node lib/doc/build site", "pretest": "npm run build", "style": "npm run style:main & npm run style:fp & npm run style:perf & npm run style:test", From e397707dc9bb870b83c4f5670e029bf2ae05bf26 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Sun, 31 Jan 2016 16:07:37 +0100 Subject: [PATCH 11/79] fp docs - translate ...args to args[] in example and params. --- lib/doc/apply-fp-mapping.js | 87 ++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/lib/doc/apply-fp-mapping.js b/lib/doc/apply-fp-mapping.js index 1f26088cef..ede0d239f1 100644 --- a/lib/doc/apply-fp-mapping.js +++ b/lib/doc/apply-fp-mapping.js @@ -32,6 +32,23 @@ function getBaseName(entry) { return _.result(/\*[\t ]*@name\s+(.+)/.exec(entry), 1, result || ''); } +/** + * Returns the new ary of a given function. + * + * @param {Object} mapping Mapping object that defines the arity of all functions. + * @param {String} name Name of the function associated to the call/function definition. + * @return {number} Ary of the function as an integer + */ +function getMethodAry(mapping, name) { + var ary = _.reduce(mapping.aryMethod, function(res, value, key) { + if (res) { + return res; + } + return _.includes(value, name) && key; + }, ''); + return _.parseInt(ary); +} + /** * Reorders `params` for a given function definition/call. * @@ -57,6 +74,49 @@ function reorderParams(mapping, name, params) { return newParams; } +var dotsRegex = /^\.\.\./; +var parensRegex = /^\((.*)\)$/; +var arrayRegex = /\[\]$/; + +/** + * Replace parameter type from something like `...number` to `number|number[]`. + * + * @param {string[]} param Array whose first item is a description of the parameter type. + * @return {string[]} `param` with the updated type. + */ +function removeDotsFromType(param) { + var type = param[0]; + if (!type.startsWith('...')) { + return param; + } + + var newType = _.chain(type) + .replace(dotsRegex, '') + .replace(parensRegex, '$1') + .split('|') + .map(function(s) { + return s.replace(arrayRegex, ''); + }) + .uniq() + .thru(function(array) { + if (array.length > 1) { + return '(' + array.join('|') + ')'; + } + return array; + }) + .thru(function(subtypes) { + return subtypes + '|' + subtypes + '[]'; + }) + .value(); + + return [newType].concat(_.tail(param)); +} + +function updateParamsDescription(mapping, entry, params) { + var paramsWithoutDots = params.map(removeDotsFromType); + return reorderParams(mapping, getBaseName(entry), paramsWithoutDots); +} + /** * Returns a function that extracts the entry's `param` data, reordered according to `mapping`. * @@ -69,12 +129,33 @@ function getReorderedParams(mapping) { // Call baseGetParams in order to compute `this._params`. baseGetParams.call(this); // Reorder params according to the `mapping`. - this._params = reorderParams(mapping, getBaseName(this.entry), this._params); + this._params = updateParamsDescription(mapping, this.entry, this._params); } return baseGetParams.call(this, index); }; } +/** + * Concatenate arguments into an array of arguments. + * For a `function fn(a, b, ...args) { ... }` with an arity of 3, + * when called with `args` [a, b, c, d, e, f], returns [a, b, [c, d, e, f]]. + * + * @param {object} j JSCodeShift object. + * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {ASTobjects[]} Arguments to concatenate. + * @return {ASTobjects[]} Concatenated arguments + */ +function concatExtraArgs(j, mapping, name, args) { + var ary = getMethodAry(mapping, name); + if (ary === args.length) { + return args; + } + return _.take(args, ary - 1).concat( + j.arrayExpression(_.takeRight(args, args.length - ary + 1)) + ); +} + /** * Updates a code sample so that the arguments in the call are reordered according to `mapping`. * @@ -87,9 +168,11 @@ function reorderParamsInExample(mapping, codeSample) { .find(j.CallExpression, { callee: { object: {name: '_' }}}) .replaceWith(function(callExpr) { var value = callExpr.value; + var name = value.callee.property.name; + var args = concatExtraArgs(j, mapping, name, value.arguments); return j.callExpression( value.callee, - reorderParams(mapping, value.callee.property.name, value.arguments) + reorderParams(mapping, name, args) ); }) .toSource(); From 5062f22839e873211c94184a877bce15b5da55ef Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Mon, 1 Feb 2016 21:17:59 +0100 Subject: [PATCH 12/79] fp docs - Remove console.log() from examples. --- lib/doc/apply-fp-mapping.js | 72 +++++++---- lib/doc/test.js | 237 ++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+), 25 deletions(-) create mode 100644 lib/doc/test.js diff --git a/lib/doc/apply-fp-mapping.js b/lib/doc/apply-fp-mapping.js index ede0d239f1..bf443773e5 100644 --- a/lib/doc/apply-fp-mapping.js +++ b/lib/doc/apply-fp-mapping.js @@ -40,13 +40,9 @@ function getBaseName(entry) { * @return {number} Ary of the function as an integer */ function getMethodAry(mapping, name) { - var ary = _.reduce(mapping.aryMethod, function(res, value, key) { - if (res) { - return res; - } - return _.includes(value, name) && key; - }, ''); - return _.parseInt(ary); + return _.find(mapping.caps, function(cap) { + return _.includes(mapping.aryMethod[cap], name) && cap; + }); } /** @@ -62,7 +58,7 @@ function reorderParams(mapping, name, params) { if (!mapping || mapping.skipRearg[name]) { return params; } - var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[params.length]; + var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[getMethodAry(mapping, name)]; if (!reargOrder) { return params; } @@ -78,6 +74,17 @@ var dotsRegex = /^\.\.\./; var parensRegex = /^\((.*)\)$/; var arrayRegex = /\[\]$/; +function wrapInParensIfMultiple(types) { + if (types.length > 1) { + return '(' + types.join('|') + ')'; + } + return types; +} + +function singleItemOrArrayOf(types) { + return types + '|' + types + '[]'; +} + /** * Replace parameter type from something like `...number` to `number|number[]`. * @@ -98,15 +105,8 @@ function removeDotsFromType(param) { return s.replace(arrayRegex, ''); }) .uniq() - .thru(function(array) { - if (array.length > 1) { - return '(' + array.join('|') + ')'; - } - return array; - }) - .thru(function(subtypes) { - return subtypes + '|' + subtypes + '[]'; - }) + .thru(wrapInParensIfMultiple) + .thru(singleItemOrArrayOf) .value(); return [newType].concat(_.tail(param)); @@ -157,16 +157,17 @@ function concatExtraArgs(j, mapping, name, args) { } /** - * Updates a code sample so that the arguments in the call are reordered according to `mapping`. + * Reorder the args in the example if needed, and eventually merges them when + * the method is called with more args than the method's ary. * + * @param {object} j JSCodeShift object. + * @param {ASTObject} root AST representation of the example * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {string} codeSample Code sample to update. - * @returns {string} Updated code sample. + * @return {ASTObject} AST object where the arguments are reordered/merged */ -function reorderParamsInExample(mapping, codeSample) { - return j(codeSample) - .find(j.CallExpression, { callee: { object: {name: '_' }}}) - .replaceWith(function(callExpr) { +function reorderMethodArgs(j, root, mapping) { + root.find(j.CallExpression, { callee: { object: {name: '_' }}}) + .replaceWith(function(callExpr, i) { var value = callExpr.value; var name = value.callee.property.name; var args = concatExtraArgs(j, mapping, name, value.arguments); @@ -174,8 +175,29 @@ function reorderParamsInExample(mapping, codeSample) { value.callee, reorderParams(mapping, name, args) ); + }); +} + +function removeConsoleLogs(codeSample) { + return codeSample + .split('\n') + .filter(function(line) { + return !line.startsWith('console.log'); }) - .toSource(); + .join('\n'); +} + +/** + * Updates a code sample so that the arguments in the call are reordered according to `mapping`. + * + * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {string} codeSample Code sample to update. + * @returns {string} Updated code sample. + */ +function reorderParamsInExample(mapping, codeSample) { + var root = j(removeConsoleLogs(codeSample)); + reorderMethodArgs(j, root, mapping); + return root.toSource(); } /** diff --git a/lib/doc/test.js b/lib/doc/test.js new file mode 100644 index 0000000000..2525e11411 --- /dev/null +++ b/lib/doc/test.js @@ -0,0 +1,237 @@ +var assert = require('assert'); + +var Entry = require('docdown/lib/entry'); + +var applyFPMapping = require('./apply-fp-mapping'); +var mapping = require('../../fp/_mapping'); + +function toExample(name, lines) { + var start = [ + "/**", + " * ", + " * @example" + ]; + var end = [ + " */", + "function " + name + "(a, b, c) {", + "", + "}" + ]; + var example = lines.map(function(line) { + return ' * ' + line; + }); + return [].concat(start, example, end).join('\n'); +} + +function toParams(name, lines) { + var start = [ + "/**", + " * ", + ]; + var end = [ + " * @returns Foo bar", + " */", + "function " + name + "(a, b, c) {", + "", + "}" + ]; + var example = lines.map(function(line) { + return ' * @param ' + line; + }); + return [].concat(start, example, end).join('\n'); +} + +describe('Docs FP mapping', function() { + var oldgetParams; + var oldgetExample; + + before(function() { + oldgetParams = Entry.prototype.getParams; + oldgetExample = Entry.prototype.getExample; + applyFPMapping(mapping); + }); + + after(function() { + Entry.prototype.getParams = oldgetParams; + Entry.prototype.getExample = oldgetExample; + }); + + describe('getExample', function() { + it('should reorder parameters', function() { + var example = toExample('differenceBy', [ + "_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);", + "// → [3.1, 1.3]", + "", + "// The `_.property` iteratee shorthand.", + "_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');", + "// → [{ 'x': 2 }]" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "_.differenceBy(Math.floor, [4.4, 2.5], [3.1, 2.2, 1.3]);", + "// → [3.1, 1.3]", + "", + "// The `_.property` iteratee shorthand.", + "_.differenceBy('x', [{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }]);", + "// → [{ 'x': 2 }]", + "```" + ].join('\n')); + }); + + it('should reorder parameters that have a special order', function() { + var example = toExample('set', [ + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set(object, 'a[0].b.c', 4);", + "_.set(object, 'x[0].y.z', 5);", + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set('a[0].b.c', 4, object);", + "_.set('x[0].y.z', 5, object);", + "```" + ].join('\n')); + }); + + it('should preserve comments', function() { + var example = toExample('set', [ + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set(object, 'a[0].b.c', 4);", + "// => 4", + "_.set(object, 'x[0].y.z', 5);", + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set('a[0].b.c', 4, object);", + "// => 4", + "_.set('x[0].y.z', 5, object);", + "```" + ].join('\n')); + }); + + it('should remove console.logs from example', function() { + var example = toExample('set', [ + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "", + "_.set(object, 'a[0].b.c', 4);", + "console.log(object.a[0].b.c);", + "// => 4", + "", + "_.set(object, 'x[0].y.z', 5);", + "console.log(object.x[0].y.z);", + "// => 5" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "", + "_.set('a[0].b.c', 4, object);", + "// => 4", + "", + "_.set('x[0].y.z', 5, object);", + "// => 5", + "```" + ].join('\n')); + }); + + it('should merge extra arguments into an array', function() { + var example = toExample('pullAt', [ + "var array = [5, 10, 15, 20];", + "var evens = _.pullAt(array, 1, 3);", + "", + "console.log(array);", + "// => [5, 15]", + "", + "console.log(evens);", + "// => [10, 20]", + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "var array = [5, 10, 15, 20];", + "var evens = _.pullAt([1, 3], array);", + "", + "// => [5, 15]", + "", + "// => [10, 20]", + "```" + ].join('\n')); + }); + }); + + describe('getParams', function() { + it('should reorder arguments', function() { + var example = toParams('differenceBy', [ + '{Array} array The array to inspect.', + '{...Array} [values] The values to exclude.', + '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Function|Object|string', '[iteratee=_.identity]', 'The iteratee invoked per element. '], + ['Array|Array[]', '[values]', 'The values to exclude. '], + ['Array', 'array', 'The array to inspect. '] + ]); + }); + + it('should reorder arguments that have a special order', function() { + var example = toParams('set', [ + '{Object} object The object to modify.', + '{Array|string} path The path of the property to set.', + '{*} value The value to set.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Array|string', 'path', 'The path of the property to set. '], + ['*', 'value', 'The value to set. '], + ['Object', 'object', 'The object to modify. '], + ]); + }); + + it('should transform rest arguments into an array', function() { + var example = toParams('pullAt', [ + '{Array} array The array to modify.', + '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + + ' * specified individually or in arrays.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + // TODO Remove this line in favor of the commented one. + // Is linked to a docdown (https://github.com/jdalton/docdown/pull/37) + // that does not handle parens in the arguments well + ['((number|number)|((number|number)[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], + // ['number|number[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], + ['Array', 'array', 'The array to modify. '], + ]); + }); + }); +}); From 39735df82fb7a34203f0db4922da04416f2a7a10 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Tue, 9 Feb 2016 13:07:42 +0100 Subject: [PATCH 13/79] fp docs - Inject default values and cap args. --- lib/doc/apply-fp-mapping.js | 334 ++++++++++++++++++++++++++++++++---- lib/doc/test.js | 249 ++++++++++++++++++++++++--- lodash.js | 6 +- package.json | 1 + 4 files changed, 525 insertions(+), 65 deletions(-) diff --git a/lib/doc/apply-fp-mapping.js b/lib/doc/apply-fp-mapping.js index bf443773e5..fa67923799 100644 --- a/lib/doc/apply-fp-mapping.js +++ b/lib/doc/apply-fp-mapping.js @@ -1,5 +1,6 @@ var _ = require('lodash'), j = require('jscodeshift'), + recast = require('recast'), Entry = require('docdown/lib/entry'); var baseGetParams = Entry.prototype.getParams; @@ -11,14 +12,25 @@ function getMultilineValue(string, tagName) { result = _.result(RegExp(prelude + '([\\s\\S]*?)' + postlude, 'gm').exec(string), 1, ''); return _.trim(result.replace(RegExp('(?:^|\\n)[\\t ]*\\*[\\t ]' + (tagName == 'example' ? '?' : '*'), 'g'), '\n')); + +} + +// Function copied from docdown/lib/entry that is not exported. +function hasTag(string, tagName) { + tagName = tagName == '*' ? '\\w+' : _.escapeRegExp(tagName); + return RegExp('^ *\\*[\\t ]*@' + tagName + '\\b', 'm').test(string); +} + +function isWrapped(entry) { + return !hasTag(entry, 'static'); } /** - * Extracts the entry's `name` data. + * Extract the entry's `name` data. * Sub-part of Entry.prototype.getCall() that fetches the name. Using `Entry.prototype.getCall()` * makes a call to getParams(), which itself call getBaseName --> infinite recursion. * - * @param {Object} entry Entry whose name to extract. + * @param {object} entry Entry whose name to extract. * @returns {string} The entry's `name` data. */ function getBaseName(entry) { @@ -33,32 +45,38 @@ function getBaseName(entry) { } /** - * Returns the new ary of a given function. + * Return the new ary of a given function. * - * @param {Object} mapping Mapping object that defines the arity of all functions. - * @param {String} name Name of the function associated to the call/function definition. + * @param {object} mapping Mapping object that defines the arity of all functions. + * @param {String} name Name of the function associated to the call/function definition. + * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. * @return {number} Ary of the function as an integer */ -function getMethodAry(mapping, name) { - return _.find(mapping.caps, function(cap) { +function getMethodAry(mapping, name, wrapped) { + var ary = _.find(mapping.caps, function(cap) { return _.includes(mapping.aryMethod[cap], name) && cap; }); + if (_.isNumber(ary) && wrapped) { + return ary - 1; + } + return ary; } /** - * Reorders `params` for a given function definition/call. + * Reorder `params` for a given function definition/call. * - * @param {Object} mapping Mapping object that defines if and how the `params` will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {*[]} params Parameters/arguments to reorder. + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {*[]} params Parameters/arguments to reorder. + * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. * @returns {*[]} Reordered parameters/arguments. */ -function reorderParams(mapping, name, params) { +function reorderParams(mapping, name, params, wrapped) { // Check if reordering is needed. if (!mapping || mapping.skipRearg[name]) { return params; } - var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[getMethodAry(mapping, name)]; + var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[getMethodAry(mapping, name, wrapped)]; if (!reargOrder) { return params; } @@ -72,28 +90,41 @@ function reorderParams(mapping, name, params) { var dotsRegex = /^\.\.\./; var parensRegex = /^\((.*)\)$/; +var squareBracketsRegex = /^\[(.*)\]$/; var arrayRegex = /\[\]$/; +/** + * Return `types` as '(X|Y|...)' if `types` contains multiple values, `types[0]` otherwise. + * + * @param {string[]} types Possible types of the parameter. + * @return {string} `types` as a string. + */ function wrapInParensIfMultiple(types) { if (types.length > 1) { return '(' + types.join('|') + ')'; } - return types; + return types[0]; } -function singleItemOrArrayOf(types) { - return types + '|' + types + '[]'; +/** + * Transform parameter type from 'X' to 'X|X[]'. + * + * @param {string[]} param Array whose first item is a description of the parameter type. + * @return {string[]} `param` with the updated type. + */ +function singleItemOrArrayOf(type) { + return type + '|' + type + '[]'; } /** * Replace parameter type from something like `...number` to `number|number[]`. * - * @param {string[]} param Array whose first item is a description of the parameter type. + * @param {string[]} param Array whose first item is a description of the parameter type. * @return {string[]} `param` with the updated type. */ -function removeDotsFromType(param) { +function removeDotsFromTypeAndAllowMultiple(param) { var type = param[0]; - if (!type.startsWith('...')) { + if (!dotsRegex.test(type)) { return param; } @@ -112,15 +143,89 @@ function removeDotsFromType(param) { return [newType].concat(_.tail(param)); } +/** + * Replace parameter type from something like `...number` to `number|number[]`. + * + * @param {string[]} param Array whose first item is a description of the parameter type. + * @return {string[]} `param` with the updated type. + */ +function removeDotsFromType(param) { + var type = param[0]; + if (!dotsRegex.test(type)) { + return param; + } + + var newType = type + .replace(dotsRegex, '') + .replace(parensRegex, '$1'); + + return [newType].concat(_.tail(param)); +} + +/** + * Find and duplicate the parameter with a type of the form '...x'. + * + * @param {string} name Name of the method. + * @param {string[]} params Description of the parameters of the method. + * @return {string[]} Updated parameters. + */ +function duplicateRestArrays(name, params) { + var indexOfRestParam = _.findIndex(params, function(param) { + return dotsRegex.test(param[0]); + }); + if (indexOfRestParam === -1) { + console.log('WARNING: method `' + name + '`', + 'is capped to more arguments than its declared number of parameters,', + 'but does not have a parameter like `...x`'); + } + // duplicates param[indexOfRestParam] at its position + return params.slice(0, indexOfRestParam + 1) + .concat(params.slice(indexOfRestParam)); +} + +/** + * Remove the optional default value and brackets around the name of the method. + * + * @param {string[]} param Array whose second item is the name of the param of the form + * 'name', '[name]' or [name=defaultValue]. + * @return {string[]} `param` with the updated name. + */ +function removeDefaultValue(param) { + var paramName = param[1] + .replace(squareBracketsRegex, '$1') + .split('=') + [0]; + + return [param[0], paramName, param[2]]; +} + function updateParamsDescription(mapping, entry, params) { - var paramsWithoutDots = params.map(removeDotsFromType); - return reorderParams(mapping, getBaseName(entry), paramsWithoutDots); + var tmpParams; + var name = getBaseName(entry); + var ary = getMethodAry(mapping, name); + + var wrapped = isWrapped(entry); + if (wrapped) { + // Needs one less argument when wrapped + ary = ary - 1; + params.shift(); + } + + if (ary > params.length) { + tmpParams = duplicateRestArrays(name, params) + .map(removeDotsFromType); + } else { + tmpParams = params + .map(removeDotsFromTypeAndAllowMultiple); + } + tmpParams = tmpParams.map(removeDefaultValue); + return reorderParams(mapping, name, tmpParams, wrapped); } /** - * Returns a function that extracts the entry's `param` data, reordered according to `mapping`. + * Return a function that extracts the entry's `param` data, reordered according to `mapping`. * - * @param {Object} mapping Mapping object that defines if and how the `params` will be reordered. + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. * @returns {Function} Function that returns the entry's `param` data. */ function getReorderedParams(mapping) { @@ -135,25 +240,160 @@ function getReorderedParams(mapping) { }; } +function getDefaultValue(paramDescription) { + var paramName = paramDescription[1]; + if (paramName[0] !== '[') { + return null; + } + return paramName + .slice(1, paramName.length - 1) + .split('=') + [1] || null; +} + +/** + * Return an AST node representation of `str`. + * + * @param {object} j JSCodeShift object. + * @param {string} str String to convert. + * @return {ASTObject} AST node. + */ +function stringToASTNode(j, str) { + return j(str).find(j.Expression).paths()[0].value; +} + +/** + * Return the name of a parameter from its description. + * @param {string[]} paramDescription Parameter description. + * @return {string} name of the parameter. + */ +function paramName(paramDescription) { + var paramName = paramDescription[1]; + if (paramName[0] !== '[') { + return paramName; + } + return paramName + .slice(1, paramName.length - 1) + .split('=') + [0]; +} + +/** + * Return a AST node representation of `object.property`. + * If `object.property` can be evaluated (ex: [].length --> 0), the node will be simplified. + * If `defaultValue` references another argument, it will be replaced by the value of that argument. + * + * @param {object} j JSCodeShift object. + * @param {ASTObject} object Object of the member expression. + * @param {string} property Property of the member expression. + * @return {ASTObject} AST node. + */ +function memberExpressiontoASTNode(j, object, property) { + var node = j.memberExpression(object, j.identifier(property)); + try { + // Attempt to evaluate the value of the node to have simpler calls + // [1, 2, 3, 4].length --> 4 + var evaluatedNode = eval(recast.print(node).code); + return stringToASTNode(j, JSON.stringify(evaluatedNode)); + } catch (e) { + return node; + } +} + +/** + * Return a AST node representation of `defaultValue`. + * If `defaultValue` references another argument, it will be replaced by the value of that argument. + * + * @param {object} j JSCodeShift object. + * @param {string} defaultValue Value to convert. + * @param {ASTObject[]} args Arguments given to the function. + * @param {string[]} paramNames Name of the expected parameters. + * @return {ASTObject} AST node representation of `defaultValue`. + */ +function defaultValueToASTNode(j, defaultValue, args, paramNames) { + // var endValue = replaceValueByArgValue(j, defaultValue, args, paramNames); + var splitDefaultValue = defaultValue.split('.'); + var indexOfReferencedParam = paramNames.indexOf(splitDefaultValue[0]); + if (indexOfReferencedParam !== -1) { + if (splitDefaultValue.length > 1) { + // defaultValue is probably of the type 'someArg.length' + // Other more complicated cases could be handled but none exist as of this writing. + return memberExpressiontoASTNode(j, args[indexOfReferencedParam], splitDefaultValue[1]); + } + return args[indexOfReferencedParam]; + } + return stringToASTNode(j, defaultValue); +} + +function mapRight(array, fn) { + var res = []; + var index = array.length; + while (index--) { + res = [fn(array[index], index)].concat(res); + } + return res; +} + +/** + * Return the list of arguments, augmented by the default value of the arguments that were ommitted. + * The augmentation only happens when the method call is made without some of the optional arguments, + * and when the arguments these optional arguments have become compulsory. + * For a `function fn(a, b, c=0, d=b.length) { ... }` with an arity of 4, + * when called with `args` [a, ['b']], returns [a, ['b'], 0, ['b'].length]. + * If possible, the value will be evaluated such that ̀`['b'].length` becomes `1`. + * + * @param {object} j JSCodeShift object. + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {ASTObject[]} args Arguments to concatenate. + * @param {string[][]} paramsDescription Description of the expected params. + * @return {ASTObject[]} Args along with missing arguments. + */ +function addMissingArguments(j, mapping, name, args, paramsDescription) { + var ary = getMethodAry(mapping, name); + + if (ary === undefined) { + console.log('WARNING: method `' + name + '` is not capped'); + } + + ary = ary || 1; + if (ary <= args.length) { + return args; + } + var paramNames = paramsDescription.map(paramName); + var tmpArgs = _.clone(args); + var newArgs = mapRight(_.take(paramsDescription, ary), function(paramDescription, index) { + if (index === tmpArgs.length - 1) { + return tmpArgs.pop(); + } + var defaultValue = getDefaultValue(paramDescription); + if (defaultValue !== null) { + return defaultValueToASTNode(j, defaultValue, args, paramNames); + } + return tmpArgs.pop(); + }); + return newArgs; +} + /** * Concatenate arguments into an array of arguments. * For a `function fn(a, b, ...args) { ... }` with an arity of 3, * when called with `args` [a, b, c, d, e, f], returns [a, b, [c, d, e, f]]. * * @param {object} j JSCodeShift object. - * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. * @param {String} name Name of the function associated to the call/function definition. - * @param {ASTobjects[]} Arguments to concatenate. - * @return {ASTobjects[]} Concatenated arguments + * @param {ASTObject[]} args Arguments to concatenate. + * @return {ASTObject[]} Concatenated arguments */ function concatExtraArgs(j, mapping, name, args) { var ary = getMethodAry(mapping, name); - if (ary === args.length) { + if (args.length <= ary) { return args; } - return _.take(args, ary - 1).concat( - j.arrayExpression(_.takeRight(args, args.length - ary + 1)) - ); + + var concatenatedArgs = j.arrayExpression(_.takeRight(args, args.length - ary + 1)); + return _.take(args, ary - 1).concat(concatenatedArgs); } /** @@ -162,15 +402,16 @@ function concatExtraArgs(j, mapping, name, args) { * * @param {object} j JSCodeShift object. * @param {ASTObject} root AST representation of the example - * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. * @return {ASTObject} AST object where the arguments are reordered/merged */ -function reorderMethodArgs(j, root, mapping) { +function reorderMethodArgs(j, root, mapping, paramsDescription) { root.find(j.CallExpression, { callee: { object: {name: '_' }}}) .replaceWith(function(callExpr, i) { var value = callExpr.value; var name = value.callee.property.name; - var args = concatExtraArgs(j, mapping, name, value.arguments); + var argsIncludingMissingOnes = addMissingArguments(j, mapping, name, value.arguments, paramsDescription) + var args = concatExtraArgs(j, mapping, name, argsIncludingMissingOnes); return j.callExpression( value.callee, reorderParams(mapping, name, args) @@ -190,21 +431,36 @@ function removeConsoleLogs(codeSample) { /** * Updates a code sample so that the arguments in the call are reordered according to `mapping`. * - * @param {Object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. * @param {string} codeSample Code sample to update. * @returns {string} Updated code sample. */ -function reorderParamsInExample(mapping, codeSample) { +function reorderParamsInExample(mapping, codeSample, paramsDescription) { var root = j(removeConsoleLogs(codeSample)); - reorderMethodArgs(j, root, mapping); + try { + reorderMethodArgs(j, root, mapping, paramsDescription); + } catch (error) { + console.error(codeSample); + console.error(error.stack); + process.exit(1); + } return root.toSource(); } +function getOriginalParams() { + var prev = this._params; + this._params = undefined; + baseGetParams.call(this); + var result = this._params; + this._params = prev; + return result; +} + /** * Returns a function that extracts the entry's `example` data, * where function call arguments are reordered according to `mapping`. * - * @param {Object} mapping Mapping object that defines if and how the `params` will be reordered. + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. * @returns {Function} Function that returns the entry's `example` data. */ function getReorderedExample(mapping) { @@ -213,7 +469,9 @@ function getReorderedExample(mapping) { if (!result) { return result; } - var resultReordered = reorderParamsInExample(mapping, result); + + var paramsDescription = getOriginalParams.call(this); + var resultReordered = reorderParamsInExample(mapping, result, paramsDescription); return '```' + this.lang + '\n' + resultReordered + '\n```'; }; } diff --git a/lib/doc/test.js b/lib/doc/test.js index 2525e11411..53c0c8ef5e 100644 --- a/lib/doc/test.js +++ b/lib/doc/test.js @@ -5,11 +5,12 @@ var Entry = require('docdown/lib/entry'); var applyFPMapping = require('./apply-fp-mapping'); var mapping = require('../../fp/_mapping'); -function toExample(name, lines) { +function toSource(name, paramLines, exampleLines, attachedToPrototype) { var start = [ "/**", " * ", - " * @example" + " * Foo", + " * " ]; var end = [ " */", @@ -17,16 +18,23 @@ function toExample(name, lines) { "", "}" ]; - var example = lines.map(function(line) { + var staticLine = attachedToPrototype ? [] : [' * @static']; + var params = paramLines.map(function(line) { + return ' * @param ' + line; + }); + var example = (exampleLines || []).map(function(line) { return ' * ' + line; }); - return [].concat(start, example, end).join('\n'); + + return [].concat(start, staticLine, params, [' * @example'], example, end).join('\n'); } -function toParams(name, lines) { +function toParams(name, lines, wrapped) { var start = [ "/**", " * ", + " * Foo", + " * " ]; var end = [ " * @returns Foo bar", @@ -35,12 +43,32 @@ function toParams(name, lines) { "", "}" ]; - var example = lines.map(function(line) { + var staticLine = wrapped ? [] : [' * @static']; + var params = lines.map(function(line) { return ' * @param ' + line; }); - return [].concat(start, example, end).join('\n'); + return [].concat(start, staticLine, params, end).join('\n'); } +var differenceBySource = toSource('differenceBy', [ + '{Array} array The array to inspect.', + '{...Array} [values] The values to exclude.', + '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' +], [ + "_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);", + "// → [3.1, 1.3]", + "", + "// The `_.property` iteratee shorthand.", + "_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');", + "// → [{ 'x': 2 }]" +]); + +var setParams = [ + '{Object} object The object to modify.', + '{Array|string} path The path of the property to set.', + '{*} value The value to set.' +]; + describe('Docs FP mapping', function() { var oldgetParams; var oldgetExample; @@ -48,6 +76,7 @@ describe('Docs FP mapping', function() { before(function() { oldgetParams = Entry.prototype.getParams; oldgetExample = Entry.prototype.getExample; + mapping.aryMethod[2].push('customFun'); applyFPMapping(mapping); }); @@ -58,15 +87,7 @@ describe('Docs FP mapping', function() { describe('getExample', function() { it('should reorder parameters', function() { - var example = toExample('differenceBy', [ - "_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);", - "// → [3.1, 1.3]", - "", - "// The `_.property` iteratee shorthand.", - "_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');", - "// → [{ 'x': 2 }]" - ]); - var entry = new Entry(example, example); + var entry = new Entry(differenceBySource, differenceBySource); var actual = entry.getExample(); @@ -83,7 +104,7 @@ describe('Docs FP mapping', function() { }); it('should reorder parameters that have a special order', function() { - var example = toExample('set', [ + var example = toSource('set', setParams, [ "var object = { 'a': [{ 'b': { 'c': 3 } }] };", "_.set(object, 'a[0].b.c', 4);", "_.set(object, 'x[0].y.z', 5);", @@ -102,7 +123,7 @@ describe('Docs FP mapping', function() { }); it('should preserve comments', function() { - var example = toExample('set', [ + var example = toSource('set', setParams, [ "var object = { 'a': [{ 'b': { 'c': 3 } }] };", "_.set(object, 'a[0].b.c', 4);", "// => 4", @@ -123,7 +144,7 @@ describe('Docs FP mapping', function() { }); it('should remove console.logs from example', function() { - var example = toExample('set', [ + var example = toSource('set', setParams, [ "var object = { 'a': [{ 'b': { 'c': 3 } }] };", "", "_.set(object, 'a[0].b.c', 4);", @@ -152,7 +173,11 @@ describe('Docs FP mapping', function() { }); it('should merge extra arguments into an array', function() { - var example = toExample('pullAt', [ + var example = toSource('pullAt', [ + '{Array} array The array to modify.', + '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + + ' * specified individually or in arrays.' + ], [ "var array = [5, 10, 15, 20];", "var evens = _.pullAt(array, 1, 3);", "", @@ -177,10 +202,139 @@ describe('Docs FP mapping', function() { "```" ].join('\n')); }); + + it('should inject default values into optional arguments that became compulsory', function() { + var example = toSource('sampleSize', [ + '{Array|Object} collection The collection to sample.', + '{number} [n=0] The number of elements to sample.' + ], [ + "_.sampleSize([1, 2, 3]);", + "// => [3, 1]", + "", + "_.sampleSize([1, 2, 3], 4);", + "// => [2, 3, 1]" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "_.sampleSize(0, [1, 2, 3]);", + "// => [3, 1]", + "", + "_.sampleSize(4, [1, 2, 3]);", + "// => [2, 3, 1]", + "```" + ].join('\n')); + }); + + it('should inject referenced values into optional arguments that became compulsory, ' + + 'if a parameter\'s default value references parameter (direct reference)', + function() { + var example = toSource('customFun', [ + '{Array} array Array', + '{number} [foo=array] Foo' + ], [ + "_.customFun([1, 2, 3]);", + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "_.customFun([1, 2, 3], [1, 2, 3]);", + "```" + ].join('\n')); + }); + + it('should inject referenced values into optional arguments that became compulsory, ' + + 'if a parameter\'s default value references parameter (member expression)', + function() { + var example = toSource('fill', [ + '{Array} array The array to fill.', + '{*} value The value to fill `array` with.', + '{number} [start=0] The start position.', + '{number} [end=array.length] The end position.' + ], [ + "var array = [1, 2, 3];", + "", + "_.fill(array, 'a');", + "console.log(array);", + "// => ['a', 'a', 'a']", + "", + "_.fill(Array(3), 2, 1);", + "// => [undefined, 2, 2]", + "", + "_.fill([4, 6, 8, 10], '*');", + "// => [*, '*', '*', *]" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "var array = [1, 2, 3];", + "", + "_.fill(0, array.length, 'a', array);", + "// => ['a', 'a', 'a']", + "", + "_.fill(1, 3, 2, Array(3));", + "// => [undefined, 2, 2]", + "", + "_.fill(0, 4, '*', [4, 6, 8, 10]);", + "// => [*, '*', '*', *]", + "```" + ].join('\n')); + }); + + it('should inject default values in the middle of the arguments', function() { + var example = toSource('inRange', [ + '{number} number The number to check.', + '{number} [start=0] The start of the range.', + '{number} end The end of the range.' + ], [ + "_.inRange(4, 8);", + "// => true" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "_.inRange(8, 0, 4);", + "// => true", + "```" + ].join('\n')); + }); + + it('should not use ignored params as default values', function() { + var example = toSource('drop', [ + '{Array} array The array to query.', + '{number} [n=1] The number of elements to drop.', + '{Object} [guard] Enables use as an iteratee for functions like `_.map`.' + ], [ + "_.drop([1, 2, 3]);", + "// => [2, 3]" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + "```js", + "_.drop(1, [1, 2, 3]);", + "// => [2, 3]", + "```" + ].join('\n')); + }); }); describe('getParams', function() { - it('should reorder arguments', function() { + it('should reorder arguments and remove default values', function() { var example = toParams('differenceBy', [ '{Array} array The array to inspect.', '{...Array} [values] The values to exclude.', @@ -191,8 +345,8 @@ describe('Docs FP mapping', function() { var actual = entry.getParams(); assert.deepEqual(actual, [ - ['Function|Object|string', '[iteratee=_.identity]', 'The iteratee invoked per element. '], - ['Array|Array[]', '[values]', 'The values to exclude. '], + ['Function|Object|string', 'iteratee', 'The iteratee invoked per element. '], + ['Array|Array[]', 'values', 'The values to exclude. '], ['Array', 'array', 'The array to inspect. '] ]); }); @@ -228,10 +382,57 @@ describe('Docs FP mapping', function() { // TODO Remove this line in favor of the commented one. // Is linked to a docdown (https://github.com/jdalton/docdown/pull/37) // that does not handle parens in the arguments well - ['((number|number)|((number|number)[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], + ['((number|number)|((number|number)[]', 'indexes', 'The indexes of elements to remove, specified individually or in arrays. '], // ['number|number[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], ['Array', 'array', 'The array to modify. '], ]); }); }); + + it('should duplicate and de-restify "rest" parameters if there are less parameters than cap', function() { + var example = toParams('intersectionWith', [ + '{...Array} [arrays] The arrays to inspect.', + '{Function} [comparator] The comparator invoked per element.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Function', 'comparator', 'The comparator invoked per element. '], + ['Array', 'arrays', 'The arrays to inspect. '], + ['Array', 'arrays', 'The arrays to inspect. '] + ]); + }); + + it('should consider method to have an ary of `ary - 1` when capped and wrapped', function() { + var wrapped = true; + var example = toParams('flatMap', [ + '{Array} array The array to iterate over.', + '{Function|Object|string} [iteratee=_.identity] The function invoked per iteration.' + ], wrapped); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Function|Object|string', 'iteratee', 'The function invoked per iteration. '] + ]); + }); + + it('should remove arguments ignored because of capping', function() { + var example = toParams('includes', [ + '{Array|Object|string} collection The collection to search.', + '{*} value The value to search for.', + '{number} [fromIndex=0] The index to search from.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['*', 'value', 'The value to search for. '], + ['Array|Object|string', 'collection', 'The collection to search. '] + ]); + }); }); diff --git a/lodash.js b/lodash.js index 954f4404d5..c824f8bbf6 100644 --- a/lodash.js +++ b/lodash.js @@ -12364,7 +12364,7 @@ * @memberOf _ * @category String * @param {string} string The string to convert. - * @param {number} [radix] The radix to interpret `value` by. + * @param {number} [radix=10] The radix to interpret `value` by. * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {number} Returns the converted integer. * @example @@ -12910,7 +12910,7 @@ * @memberOf _ * @category String * @param {string} [string=''] The string to truncate. - * @param {Object} [options] The options object. + * @param {Object} [options=({})] The options object. * @param {number} [options.length=30] The maximum string length. * @param {string} [options.omission='...'] The string to indicate text is omitted. * @param {RegExp|string} [options.separator] The separator pattern to truncate to. @@ -13829,7 +13829,7 @@ * @static * @memberOf _ * @category Util - * @param {string} [prefix] The value to prefix the ID with. + * @param {string} [prefix=''] The value to prefix the ID with. * @returns {string} Returns the unique ID. * @example * diff --git a/package.json b/package.json index 40433ada86..6066accfc2 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "platform": "^1.3.1", "qunit-extras": "^1.4.5", "qunitjs": "~1.21.0", + "recast": "^0.11.0", "request": "^2.69.0", "requirejs": "^2.1.22", "sauce-tunnel": "^2.4.0", From 6f4099c20bc2695327923c13da3a308ad80275c8 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Tue, 9 Feb 2016 11:03:34 +0100 Subject: [PATCH 14/79] fp docs - Split lib/doc/apply-fp-mapping into multiples files. --- lib/doc/apply-fp-mapping.js | 485 ----------------------- lib/doc/apply-fp-mapping/common.js | 72 ++++ lib/doc/apply-fp-mapping/example.js | 268 +++++++++++++ lib/doc/apply-fp-mapping/index.js | 11 + lib/doc/apply-fp-mapping/parameters.js | 206 ++++++++++ lib/doc/test.js | 438 --------------------- package.json | 3 +- test/test-fp-doc.js | 508 +++++++++++++++++++++++++ 8 files changed, 1067 insertions(+), 924 deletions(-) delete mode 100644 lib/doc/apply-fp-mapping.js create mode 100644 lib/doc/apply-fp-mapping/common.js create mode 100644 lib/doc/apply-fp-mapping/example.js create mode 100644 lib/doc/apply-fp-mapping/index.js create mode 100644 lib/doc/apply-fp-mapping/parameters.js delete mode 100644 lib/doc/test.js create mode 100644 test/test-fp-doc.js diff --git a/lib/doc/apply-fp-mapping.js b/lib/doc/apply-fp-mapping.js deleted file mode 100644 index fa67923799..0000000000 --- a/lib/doc/apply-fp-mapping.js +++ /dev/null @@ -1,485 +0,0 @@ -var _ = require('lodash'), - j = require('jscodeshift'), - recast = require('recast'), - Entry = require('docdown/lib/entry'); - -var baseGetParams = Entry.prototype.getParams; - -// Function copied from docdown/lib/entry that is not exported. -function getMultilineValue(string, tagName) { - var prelude = tagName == 'description' ? '^ */\\*\\*(?: *\\n *\\* *)?' : ('^ *\\*[\\t ]*@' + _.escapeRegExp(tagName) + '\\b'), - postlude = '(?=\\*\\s+\\@[a-z]|\\*/)', - result = _.result(RegExp(prelude + '([\\s\\S]*?)' + postlude, 'gm').exec(string), 1, ''); - - return _.trim(result.replace(RegExp('(?:^|\\n)[\\t ]*\\*[\\t ]' + (tagName == 'example' ? '?' : '*'), 'g'), '\n')); - -} - -// Function copied from docdown/lib/entry that is not exported. -function hasTag(string, tagName) { - tagName = tagName == '*' ? '\\w+' : _.escapeRegExp(tagName); - return RegExp('^ *\\*[\\t ]*@' + tagName + '\\b', 'm').test(string); -} - -function isWrapped(entry) { - return !hasTag(entry, 'static'); -} - -/** - * Extract the entry's `name` data. - * Sub-part of Entry.prototype.getCall() that fetches the name. Using `Entry.prototype.getCall()` - * makes a call to getParams(), which itself call getBaseName --> infinite recursion. - * - * @param {object} entry Entry whose name to extract. - * @returns {string} The entry's `name` data. - */ -function getBaseName(entry) { - var result = /\*\/\s*(?:function\s+([^(]*)|(.*?)(?=[:=,]))/.exec(entry); - if (result) { - result = (result[1] || result[2]).split('.').pop(); - result = _.trim(_.trim(result), "'").split('var ').pop(); - result = _.trim(result); - } - // Get the function name. - return _.result(/\*[\t ]*@name\s+(.+)/.exec(entry), 1, result || ''); -} - -/** - * Return the new ary of a given function. - * - * @param {object} mapping Mapping object that defines the arity of all functions. - * @param {String} name Name of the function associated to the call/function definition. - * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. - * @return {number} Ary of the function as an integer - */ -function getMethodAry(mapping, name, wrapped) { - var ary = _.find(mapping.caps, function(cap) { - return _.includes(mapping.aryMethod[cap], name) && cap; - }); - if (_.isNumber(ary) && wrapped) { - return ary - 1; - } - return ary; -} - -/** - * Reorder `params` for a given function definition/call. - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {*[]} params Parameters/arguments to reorder. - * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. - * @returns {*[]} Reordered parameters/arguments. - */ -function reorderParams(mapping, name, params, wrapped) { - // Check if reordering is needed. - if (!mapping || mapping.skipRearg[name]) { - return params; - } - var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[getMethodAry(mapping, name, wrapped)]; - if (!reargOrder) { - return params; - } - // Reorder params. - var newParams = []; - reargOrder.forEach(function(newPosition, index) { - newParams[newPosition] = params[index]; - }); - return newParams; -} - -var dotsRegex = /^\.\.\./; -var parensRegex = /^\((.*)\)$/; -var squareBracketsRegex = /^\[(.*)\]$/; -var arrayRegex = /\[\]$/; - -/** - * Return `types` as '(X|Y|...)' if `types` contains multiple values, `types[0]` otherwise. - * - * @param {string[]} types Possible types of the parameter. - * @return {string} `types` as a string. - */ -function wrapInParensIfMultiple(types) { - if (types.length > 1) { - return '(' + types.join('|') + ')'; - } - return types[0]; -} - -/** - * Transform parameter type from 'X' to 'X|X[]'. - * - * @param {string[]} param Array whose first item is a description of the parameter type. - * @return {string[]} `param` with the updated type. - */ -function singleItemOrArrayOf(type) { - return type + '|' + type + '[]'; -} - -/** - * Replace parameter type from something like `...number` to `number|number[]`. - * - * @param {string[]} param Array whose first item is a description of the parameter type. - * @return {string[]} `param` with the updated type. - */ -function removeDotsFromTypeAndAllowMultiple(param) { - var type = param[0]; - if (!dotsRegex.test(type)) { - return param; - } - - var newType = _.chain(type) - .replace(dotsRegex, '') - .replace(parensRegex, '$1') - .split('|') - .map(function(s) { - return s.replace(arrayRegex, ''); - }) - .uniq() - .thru(wrapInParensIfMultiple) - .thru(singleItemOrArrayOf) - .value(); - - return [newType].concat(_.tail(param)); -} - -/** - * Replace parameter type from something like `...number` to `number|number[]`. - * - * @param {string[]} param Array whose first item is a description of the parameter type. - * @return {string[]} `param` with the updated type. - */ -function removeDotsFromType(param) { - var type = param[0]; - if (!dotsRegex.test(type)) { - return param; - } - - var newType = type - .replace(dotsRegex, '') - .replace(parensRegex, '$1'); - - return [newType].concat(_.tail(param)); -} - -/** - * Find and duplicate the parameter with a type of the form '...x'. - * - * @param {string} name Name of the method. - * @param {string[]} params Description of the parameters of the method. - * @return {string[]} Updated parameters. - */ -function duplicateRestArrays(name, params) { - var indexOfRestParam = _.findIndex(params, function(param) { - return dotsRegex.test(param[0]); - }); - if (indexOfRestParam === -1) { - console.log('WARNING: method `' + name + '`', - 'is capped to more arguments than its declared number of parameters,', - 'but does not have a parameter like `...x`'); - } - // duplicates param[indexOfRestParam] at its position - return params.slice(0, indexOfRestParam + 1) - .concat(params.slice(indexOfRestParam)); -} - -/** - * Remove the optional default value and brackets around the name of the method. - * - * @param {string[]} param Array whose second item is the name of the param of the form - * 'name', '[name]' or [name=defaultValue]. - * @return {string[]} `param` with the updated name. - */ -function removeDefaultValue(param) { - var paramName = param[1] - .replace(squareBracketsRegex, '$1') - .split('=') - [0]; - - return [param[0], paramName, param[2]]; -} - -function updateParamsDescription(mapping, entry, params) { - var tmpParams; - var name = getBaseName(entry); - var ary = getMethodAry(mapping, name); - - var wrapped = isWrapped(entry); - if (wrapped) { - // Needs one less argument when wrapped - ary = ary - 1; - params.shift(); - } - - if (ary > params.length) { - tmpParams = duplicateRestArrays(name, params) - .map(removeDotsFromType); - } else { - tmpParams = params - .map(removeDotsFromTypeAndAllowMultiple); - } - tmpParams = tmpParams.map(removeDefaultValue); - return reorderParams(mapping, name, tmpParams, wrapped); -} - -/** - * Return a function that extracts the entry's `param` data, reordered according to `mapping`. - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @returns {Function} Function that returns the entry's `param` data. - */ -function getReorderedParams(mapping) { - return function(index) { - if (!this._params) { - // Call baseGetParams in order to compute `this._params`. - baseGetParams.call(this); - // Reorder params according to the `mapping`. - this._params = updateParamsDescription(mapping, this.entry, this._params); - } - return baseGetParams.call(this, index); - }; -} - -function getDefaultValue(paramDescription) { - var paramName = paramDescription[1]; - if (paramName[0] !== '[') { - return null; - } - return paramName - .slice(1, paramName.length - 1) - .split('=') - [1] || null; -} - -/** - * Return an AST node representation of `str`. - * - * @param {object} j JSCodeShift object. - * @param {string} str String to convert. - * @return {ASTObject} AST node. - */ -function stringToASTNode(j, str) { - return j(str).find(j.Expression).paths()[0].value; -} - -/** - * Return the name of a parameter from its description. - * @param {string[]} paramDescription Parameter description. - * @return {string} name of the parameter. - */ -function paramName(paramDescription) { - var paramName = paramDescription[1]; - if (paramName[0] !== '[') { - return paramName; - } - return paramName - .slice(1, paramName.length - 1) - .split('=') - [0]; -} - -/** - * Return a AST node representation of `object.property`. - * If `object.property` can be evaluated (ex: [].length --> 0), the node will be simplified. - * If `defaultValue` references another argument, it will be replaced by the value of that argument. - * - * @param {object} j JSCodeShift object. - * @param {ASTObject} object Object of the member expression. - * @param {string} property Property of the member expression. - * @return {ASTObject} AST node. - */ -function memberExpressiontoASTNode(j, object, property) { - var node = j.memberExpression(object, j.identifier(property)); - try { - // Attempt to evaluate the value of the node to have simpler calls - // [1, 2, 3, 4].length --> 4 - var evaluatedNode = eval(recast.print(node).code); - return stringToASTNode(j, JSON.stringify(evaluatedNode)); - } catch (e) { - return node; - } -} - -/** - * Return a AST node representation of `defaultValue`. - * If `defaultValue` references another argument, it will be replaced by the value of that argument. - * - * @param {object} j JSCodeShift object. - * @param {string} defaultValue Value to convert. - * @param {ASTObject[]} args Arguments given to the function. - * @param {string[]} paramNames Name of the expected parameters. - * @return {ASTObject} AST node representation of `defaultValue`. - */ -function defaultValueToASTNode(j, defaultValue, args, paramNames) { - // var endValue = replaceValueByArgValue(j, defaultValue, args, paramNames); - var splitDefaultValue = defaultValue.split('.'); - var indexOfReferencedParam = paramNames.indexOf(splitDefaultValue[0]); - if (indexOfReferencedParam !== -1) { - if (splitDefaultValue.length > 1) { - // defaultValue is probably of the type 'someArg.length' - // Other more complicated cases could be handled but none exist as of this writing. - return memberExpressiontoASTNode(j, args[indexOfReferencedParam], splitDefaultValue[1]); - } - return args[indexOfReferencedParam]; - } - return stringToASTNode(j, defaultValue); -} - -function mapRight(array, fn) { - var res = []; - var index = array.length; - while (index--) { - res = [fn(array[index], index)].concat(res); - } - return res; -} - -/** - * Return the list of arguments, augmented by the default value of the arguments that were ommitted. - * The augmentation only happens when the method call is made without some of the optional arguments, - * and when the arguments these optional arguments have become compulsory. - * For a `function fn(a, b, c=0, d=b.length) { ... }` with an arity of 4, - * when called with `args` [a, ['b']], returns [a, ['b'], 0, ['b'].length]. - * If possible, the value will be evaluated such that ̀`['b'].length` becomes `1`. - * - * @param {object} j JSCodeShift object. - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {ASTObject[]} args Arguments to concatenate. - * @param {string[][]} paramsDescription Description of the expected params. - * @return {ASTObject[]} Args along with missing arguments. - */ -function addMissingArguments(j, mapping, name, args, paramsDescription) { - var ary = getMethodAry(mapping, name); - - if (ary === undefined) { - console.log('WARNING: method `' + name + '` is not capped'); - } - - ary = ary || 1; - if (ary <= args.length) { - return args; - } - var paramNames = paramsDescription.map(paramName); - var tmpArgs = _.clone(args); - var newArgs = mapRight(_.take(paramsDescription, ary), function(paramDescription, index) { - if (index === tmpArgs.length - 1) { - return tmpArgs.pop(); - } - var defaultValue = getDefaultValue(paramDescription); - if (defaultValue !== null) { - return defaultValueToASTNode(j, defaultValue, args, paramNames); - } - return tmpArgs.pop(); - }); - return newArgs; -} - -/** - * Concatenate arguments into an array of arguments. - * For a `function fn(a, b, ...args) { ... }` with an arity of 3, - * when called with `args` [a, b, c, d, e, f], returns [a, b, [c, d, e, f]]. - * - * @param {object} j JSCodeShift object. - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {ASTObject[]} args Arguments to concatenate. - * @return {ASTObject[]} Concatenated arguments - */ -function concatExtraArgs(j, mapping, name, args) { - var ary = getMethodAry(mapping, name); - if (args.length <= ary) { - return args; - } - - var concatenatedArgs = j.arrayExpression(_.takeRight(args, args.length - ary + 1)); - return _.take(args, ary - 1).concat(concatenatedArgs); -} - -/** - * Reorder the args in the example if needed, and eventually merges them when - * the method is called with more args than the method's ary. - * - * @param {object} j JSCodeShift object. - * @param {ASTObject} root AST representation of the example - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @return {ASTObject} AST object where the arguments are reordered/merged - */ -function reorderMethodArgs(j, root, mapping, paramsDescription) { - root.find(j.CallExpression, { callee: { object: {name: '_' }}}) - .replaceWith(function(callExpr, i) { - var value = callExpr.value; - var name = value.callee.property.name; - var argsIncludingMissingOnes = addMissingArguments(j, mapping, name, value.arguments, paramsDescription) - var args = concatExtraArgs(j, mapping, name, argsIncludingMissingOnes); - return j.callExpression( - value.callee, - reorderParams(mapping, name, args) - ); - }); -} - -function removeConsoleLogs(codeSample) { - return codeSample - .split('\n') - .filter(function(line) { - return !line.startsWith('console.log'); - }) - .join('\n'); -} - -/** - * Updates a code sample so that the arguments in the call are reordered according to `mapping`. - * - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {string} codeSample Code sample to update. - * @returns {string} Updated code sample. - */ -function reorderParamsInExample(mapping, codeSample, paramsDescription) { - var root = j(removeConsoleLogs(codeSample)); - try { - reorderMethodArgs(j, root, mapping, paramsDescription); - } catch (error) { - console.error(codeSample); - console.error(error.stack); - process.exit(1); - } - return root.toSource(); -} - -function getOriginalParams() { - var prev = this._params; - this._params = undefined; - baseGetParams.call(this); - var result = this._params; - this._params = prev; - return result; -} - -/** - * Returns a function that extracts the entry's `example` data, - * where function call arguments are reordered according to `mapping`. - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @returns {Function} Function that returns the entry's `example` data. - */ -function getReorderedExample(mapping) { - return function() { - var result = getMultilineValue(this.entry, 'example'); - if (!result) { - return result; - } - - var paramsDescription = getOriginalParams.call(this); - var resultReordered = reorderParamsInExample(mapping, result, paramsDescription); - return '```' + this.lang + '\n' + resultReordered + '\n```'; - }; -} - -/** - * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`. - */ -module.exports = function applyFPMapping(mapping) { - Entry.prototype.getParams = getReorderedParams(mapping); - Entry.prototype.getExample = getReorderedExample(mapping); -}; diff --git a/lib/doc/apply-fp-mapping/common.js b/lib/doc/apply-fp-mapping/common.js new file mode 100644 index 0000000000..ed510aa502 --- /dev/null +++ b/lib/doc/apply-fp-mapping/common.js @@ -0,0 +1,72 @@ +var _ = require('lodash'), + Entry = require('docdown/lib/entry'); + +var baseGetParams = Entry.prototype.getParams; + +// Function copied from docdown/lib/entry that is not exported. +function getMultilineValue(string, tagName) { + var prelude = tagName == 'description' ? '^ */\\*\\*(?: *\\n *\\* *)?' : ('^ *\\*[\\t ]*@' + _.escapeRegExp(tagName) + '\\b'), + postlude = '(?=\\*\\s+\\@[a-z]|\\*/)', + result = _.result(RegExp(prelude + '([\\s\\S]*?)' + postlude, 'gm').exec(string), 1, ''); + + return _.trim(result.replace(RegExp('(?:^|\\n)[\\t ]*\\*[\\t ]' + (tagName == 'example' ? '?' : '*'), 'g'), '\n')); + +} + +// Function copied from docdown/lib/entry that is not exported. +function hasTag(string, tagName) { + tagName = tagName == '*' ? '\\w+' : _.escapeRegExp(tagName); + return RegExp('^ *\\*[\\t ]*@' + tagName + '\\b', 'm').test(string); +} + +/** + * Return the new ary of a given function. + * + * @param {object} mapping Mapping object that defines the arity of all functions. + * @param {String} name Name of the function associated to the call/function definition. + * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. + * @return {number} Ary of the function as an integer + */ +function getMethodAry(mapping, name, wrapped) { + var ary = _.find(mapping.caps, function(cap) { + return _.includes(mapping.aryMethod[cap], name) && cap; + }); + if (_.isNumber(ary) && wrapped) { + return ary - 1; + } + return ary; +} + +/** + * Reorder `params` for a given function definition/call. + * + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {*[]} params Parameters/arguments to reorder. + * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. + * @returns {*[]} Reordered parameters/arguments. + */ +function reorderParams(mapping, name, params, wrapped) { + // Check if reordering is needed. + if (!mapping || mapping.skipRearg[name]) { + return params; + } + var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[getMethodAry(mapping, name, wrapped)]; + if (!reargOrder) { + return params; + } + // Reorder params. + var newParams = []; + reargOrder.forEach(function(newPosition, index) { + newParams[newPosition] = params[index]; + }); + return newParams; +} + +module.exports = { + baseGetParams: baseGetParams, + getMultilineValue: getMultilineValue, + hasTag: hasTag, + getMethodAry: getMethodAry, + reorderParams: reorderParams +}; diff --git a/lib/doc/apply-fp-mapping/example.js b/lib/doc/apply-fp-mapping/example.js new file mode 100644 index 0000000000..fefe4109d0 --- /dev/null +++ b/lib/doc/apply-fp-mapping/example.js @@ -0,0 +1,268 @@ +var _ = require('lodash'), + recast = require('recast'), + j = require('jscodeshift'), + common = require('./common'); + +/** + * Return the name of a parameter from its description. + * + * @param {string[]} paramDescription Parameter description. + * @return {string} name of the parameter. + */ +function paramName(paramDescription) { + var name = paramDescription[1]; + if (name[0] !== '[') { + return name; + } + return name + .slice(1, name.length - 1) + .split('=') + [0]; +} + +/** + * Return the default value of the given parameter. + * + * @param {string[]} paramDescription Parameter description. + * @return {string} Default value as string if found, null otherwise. + */ +function getDefaultValue(paramDescription) { + var name = paramDescription[1]; + if (name[0] !== '[') { + return null; + } + return name + .slice(1, name.length - 1) + .split('=') + [1] || null; +} + +/** + * Return an AST node representation of `str`. + * + * @param {object} j JSCodeShift object. + * @param {string} str String to convert. + * @return {ASTObject} AST node. + */ +function stringToASTNode(j, str) { + return j(str).find(j.Expression).paths()[0].value; +} + +/** + * Return a AST node representation of `object.property`. + * If `object.property` can be evaluated (ex: [].length --> 0), the node will be simplified. + * If `defaultValue` references another argument, it will be replaced by the value of that argument. + * + * @param {object} j JSCodeShift object. + * @param {ASTObject} object Object of the member expression. + * @param {string} property Property of the member expression. + * @return {ASTObject} AST node. + */ +function memberExpressiontoASTNode(j, object, property) { + var node = j.memberExpression(object, j.identifier(property)); + try { + // Attempt to evaluate the value of the node to have simpler calls + // [1, 2, 3, 4].length --> 4 + var evaluatedNode = eval(recast.print(node).code); + return stringToASTNode(j, JSON.stringify(evaluatedNode)); + } catch (e) { + return node; + } +} + +/** + * Return a AST node representation of `defaultValue`. + * If `defaultValue` references another argument, it will be replaced by the value of that argument. + * + * @param {object} j JSCodeShift object. + * @param {string} defaultValue Value to convert. + * @param {ASTObject[]} args Arguments given to the function. + * @param {string[]} paramNames Name of the expected parameters. + * @return {ASTObject} AST node representation of `defaultValue`. + */ +function defaultValueToASTNode(j, defaultValue, args, paramNames) { + // var endValue = replaceValueByArgValue(j, defaultValue, args, paramNames); + var splitDefaultValue = defaultValue.split('.'); + var indexOfReferencedParam = paramNames.indexOf(splitDefaultValue[0]); + if (indexOfReferencedParam !== -1) { + if (splitDefaultValue.length > 1) { + // defaultValue is probably of the type 'someArg.length' + // Other more complicated cases could be handled but none exist as of this writing. + return memberExpressiontoASTNode(j, args[indexOfReferencedParam], splitDefaultValue[1]); + } + return args[indexOfReferencedParam]; + } + return stringToASTNode(j, defaultValue); +} + +/** + * Same as _.map, but applied in reverse order. + * + * @param {Array} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @return {Array} Returns the new mapped array. + */ +function mapRight(array, iteratee) { + var res = []; + var index = array.length; + while (index--) { + res = [iteratee(array[index], index)].concat(res); + } + return res; +} + +/** + * Return the list of arguments, augmented by the default value of the arguments that were ommitted. + * The augmentation only happens when the method call is made without some of the optional arguments, + * and when the arguments these optional arguments have become compulsory. + * For a `function fn(a, b, c=0, d=b.length) { ... }` with an arity of 4, + * when called with `args` [a, ['b']], returns [a, ['b'], 0, ['b'].length]. + * If possible, the value will be evaluated such that ̀`['b'].length` becomes `1`. + * + * @param {object} j JSCodeShift object. + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {ASTObject[]} args Arguments to concatenate. + * @param {string[][]} paramsDescription Description of the expected params. + * @return {ASTObject[]} Args along with missing arguments. + */ +function addMissingArguments(j, mapping, name, args, paramsDescription) { + var ary = common.getMethodAry(mapping, name); + + if (ary === undefined) { + console.log('WARNING: method `' + name + '` is not capped'); + } + + ary = ary || 1; + if (ary <= args.length) { + return args; + } + var paramNames = paramsDescription.map(paramName); + var tmpArgs = _.clone(args); + var newArgs = mapRight(_.take(paramsDescription, ary), function(paramDescription, index) { + if (index === tmpArgs.length - 1) { + return tmpArgs.pop(); + } + var defaultValue = getDefaultValue(paramDescription); + if (defaultValue !== null) { + return defaultValueToASTNode(j, defaultValue, args, paramNames); + } + return tmpArgs.pop(); + }); + return newArgs; +} + +/** + * Concatenate arguments into an array of arguments. + * For a `function fn(a, b, ...args) { ... }` with an arity of 3, + * when called with `args` [a, b, c, d, e, f], returns [a, b, [c, d, e, f]]. + * + * @param {object} j JSCodeShift object. + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {String} name Name of the function associated to the call/function definition. + * @param {ASTObject[]} args Arguments to concatenate. + * @return {ASTObject[]} Concatenated arguments + */ +function concatExtraArgs(j, mapping, name, args) { + var ary = common.getMethodAry(mapping, name); + if (args.length <= ary) { + return args; + } + + var concatenatedArgs = j.arrayExpression(_.takeRight(args, args.length - ary + 1)); + return _.take(args, ary - 1).concat(concatenatedArgs); +} + +/** + * Reorder the args in the example if needed, and eventually merges them when + * the method is called with more args than the method's ary. + * + * @param {object} j JSCodeShift object. + * @param {ASTObject} root AST representation of the example + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. + * @return {ASTObject} AST object where the arguments are reordered/merged + */ +function reorderMethodArgs(j, root, mapping, paramsDescription) { + root.find(j.CallExpression, { callee: { object: {name: '_' }}}) + .replaceWith(function(callExpr, i) { + var value = callExpr.value; + var name = value.callee.property.name; + var argsIncludingMissingOnes = addMissingArguments(j, mapping, name, value.arguments, paramsDescription); + var args = concatExtraArgs(j, mapping, name, argsIncludingMissingOnes); + return j.callExpression( + value.callee, + common.reorderParams(mapping, name, args) + ); + }); +} + +/** + * Remove calls to `console.log` from `codeSample`. + * + * @param {string} codeSample string to remove the calls from. + * @return {string} Updated code sample. + */ +function removeConsoleLogs(codeSample) { + return codeSample + .split('\n') + .filter(function(line) { + return !line.startsWith('console.log'); + }) + .join('\n'); +} + +/** + * Updates a code sample so that the arguments in the call are reordered according to `mapping`. + * + * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. + * @param {string} codeSample Code sample to update. + * @returns {string} Updated code sample. + */ +function reorderParamsInExample(mapping, codeSample, paramsDescription) { + var root = j(removeConsoleLogs(codeSample)); + try { + reorderMethodArgs(j, root, mapping, paramsDescription); + } catch (error) { + console.error(codeSample); + console.error(error.stack); + process.exit(1); + } + return root.toSource(); +} + +/** + * Returns the original, not reordered, list of parameters. + * + * @param {Entry} entryItem Entry whose parameters to get. + * @return {string[][]} List of args. + */ +function getOriginalParams(entryItem) { + var prev = entryItem._params; + entryItem._params = undefined; + common.baseGetParams.call(entryItem); + var result = entryItem._params; + entryItem._params = prev; + return result; +} + +/** + * Returns a function that extracts the entry's `example` data, + * where function call arguments are reordered according to `mapping`. + * + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. + * @returns {Function} Function that returns the entry's `example` data. + */ +function getReorderedExample(mapping) { + return function() { + var result = common.getMultilineValue(this.entry, 'example'); + if (!result) { + return result; + } + + var paramsDescription = getOriginalParams(this); + var resultReordered = reorderParamsInExample(mapping, result, paramsDescription); + return '```' + this.lang + '\n' + resultReordered + '\n```'; + }; +} + +module.exports = getReorderedExample; diff --git a/lib/doc/apply-fp-mapping/index.js b/lib/doc/apply-fp-mapping/index.js new file mode 100644 index 0000000000..0b9bbc5f48 --- /dev/null +++ b/lib/doc/apply-fp-mapping/index.js @@ -0,0 +1,11 @@ +var Entry = require('docdown/lib/entry'), + getReorderedParams = require('./parameters'), + getReorderedExample = require('./example'); + +/** + * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`. + */ +module.exports = function applyFPMapping(mapping) { + Entry.prototype.getParams = getReorderedParams(mapping); + Entry.prototype.getExample = getReorderedExample(mapping); +}; diff --git a/lib/doc/apply-fp-mapping/parameters.js b/lib/doc/apply-fp-mapping/parameters.js new file mode 100644 index 0000000000..3b0713aa28 --- /dev/null +++ b/lib/doc/apply-fp-mapping/parameters.js @@ -0,0 +1,206 @@ +var _ = require('lodash'), + j = require('jscodeshift'), + Entry = require('docdown/lib/entry'), + common = require('./common'); + +var baseGetParams = Entry.prototype.getParams; + +var dotsRegex = /^\.\.\./; +var parensRegex = /^\((.*)\)$/; +var squareBracketsRegex = /^\[(.*)\]$/; +var arrayRegex = /\[\]$/; + +/** + * Return whether method is wrapped. + * + * @param {Entry} entry Entry to look at. + * @return {Boolean} true if the method is wrapped, false if it is static. + */ +function isWrapped(entry) { + return !common.hasTag(entry, 'static'); +} + +/** + * Extract the entry's `name` data. + * Sub-part of Entry.prototype.getCall() that fetches the name. Using `Entry.prototype.getCall()` + * makes a call to getParams(), which itself call getBaseName --> infinite recursion. + * + * @param {object} entry Entry whose name to extract. + * @returns {string} The entry's `name` data. + */ +function getBaseName(entry) { + var result = /\*\/\s*(?:function\s+([^(]*)|(.*?)(?=[:=,]))/.exec(entry); + if (result) { + result = (result[1] || result[2]).split('.').pop(); + result = _.trim(_.trim(result), "'").split('var ').pop(); + result = _.trim(result); + } + // Get the function name. + return _.result(/\*[\t ]*@name\s+(.+)/.exec(entry), 1, result || ''); +} + +/** + * Return `types` as '(X|Y|...)' if `types` contains multiple values, `types[0]` otherwise. + * + * @param {string[]} types Possible types of the parameter. + * @return {string} `types` as a string. + */ +function wrapInParensIfMultiple(types) { + if (types.length > 1) { + return '(' + types.join('|') + ')'; + } + return types[0]; +} + +/** + * Transform parameter type from 'X' to 'X|X[]'. + * + * @param {string[]} param Array whose first item is a description of the parameter type. + * @return {string[]} `param` with the updated type. + */ +function singleItemOrArrayOf(type) { + return type + '|' + type + '[]'; +} + +/** + * Replace parameter type from something like `...number` to `number|number[]`. + * + * @param {string[]} param Array whose first item is a description of the parameter type. + * @return {string[]} `param` with the updated type. + */ +function removeDotsFromTypeAndAllowMultiple(param) { + var type = param[0]; + if (!dotsRegex.test(type)) { + return param; + } + + var newType = _.chain(type) + .replace(dotsRegex, '') + .replace(parensRegex, '$1') + .split('|') + .map(function(s) { + return s.replace(arrayRegex, ''); + }) + .uniq() + .thru(wrapInParensIfMultiple) + .thru(singleItemOrArrayOf) + .value(); + + return [newType].concat(_.tail(param)); +} + +/** + * Replace parameter type from something like `...number` to `number|number[]`. + * + * @param {string[]} param Array whose first item is a description of the parameter type. + * @return {string[]} `param` with the updated type. + */ +function removeDotsFromType(param) { + var type = param[0]; + if (!dotsRegex.test(type)) { + return param; + } + + var newType = type + .replace(dotsRegex, '') + .replace(parensRegex, '$1'); + + return [newType].concat(_.tail(param)); +} + +/** + * Find and duplicate the parameter with a type of the form '...x'. + * + * @param {string} name Name of the method. + * @param {string[]} params Description of the parameters of the method. + * @return {string[]} Updated parameters. + */ +function duplicateRestArrays(name, params) { + var indexOfRestParam = _.findIndex(params, function(param) { + return dotsRegex.test(param[0]); + }); + if (indexOfRestParam === -1) { + console.log('WARNING: method `' + name + '`', + 'is capped to more arguments than its declared number of parameters,', + 'but does not have a parameter like `...x`'); + } + // duplicates param[indexOfRestParam] at its position + return params.slice(0, indexOfRestParam + 1) + .concat(params.slice(indexOfRestParam)); +} + +/** + * Remove the optional default value and brackets around the name of the method. + * + * @param {string[]} param Array whose second item is the name of the param of the form + * 'name', '[name]' or [name=defaultValue]. + * @return {string[]} `param` with the updated name. + */ +function removeDefaultValue(param) { + var name = param[1] + .replace(squareBracketsRegex, '$1') + .split('=') + [0]; + + return [param[0], name, param[2]]; +} + +/** + * Return the updated list of parameters of a method described by `entry`, + * according to changes described by `mapping`. Will, if needed: + * - reorder the arguments + * - remove default values and brackets around previously optional arguments + * - remove ignored arguments + * - duplicate rest arguments if the number of params is less than its cap + * - de-restify arguments + * + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. + * @param {Entry} entry Method to update. + * @param {string[][]} params List of the original parameters of the method. + * @return {string[][]} Updated list of params. + */ +function updateParamsDescription(mapping, entry, params) { + var tmpParams; + var name = getBaseName(entry); + var ary = common.getMethodAry(mapping, name); + + var wrapped = isWrapped(entry); + if (wrapped) { + // Needs one less argument when wrapped + ary = ary - 1; + params.shift(); + } + + if (ary > params.length) { + tmpParams = duplicateRestArrays(name, params) + .map(removeDotsFromType); + } else { + tmpParams = params + .map(removeDotsFromTypeAndAllowMultiple); + } + tmpParams = _.take(tmpParams, ary).map(removeDefaultValue); + return common.reorderParams(mapping, name, tmpParams, wrapped); +} + +/** + * Return a function that extracts the entry's `param` data, reordered according to `mapping`. + * + * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. + * @returns {Function} Function that returns the entry's `param` data. + */ +function getReorderedParams(mapping) { + return function(index) { + if (!this._params) { + // Call baseGetParams in order to compute `this._params`. + baseGetParams.call(this); + // Reorder params according to the `mapping`. + this._params = updateParamsDescription(mapping, this.entry, this._params); + } + return baseGetParams.call(this, index); + }; +} + +/** + * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`. + */ +module.exports = getReorderedParams; diff --git a/lib/doc/test.js b/lib/doc/test.js deleted file mode 100644 index 53c0c8ef5e..0000000000 --- a/lib/doc/test.js +++ /dev/null @@ -1,438 +0,0 @@ -var assert = require('assert'); - -var Entry = require('docdown/lib/entry'); - -var applyFPMapping = require('./apply-fp-mapping'); -var mapping = require('../../fp/_mapping'); - -function toSource(name, paramLines, exampleLines, attachedToPrototype) { - var start = [ - "/**", - " * ", - " * Foo", - " * " - ]; - var end = [ - " */", - "function " + name + "(a, b, c) {", - "", - "}" - ]; - var staticLine = attachedToPrototype ? [] : [' * @static']; - var params = paramLines.map(function(line) { - return ' * @param ' + line; - }); - var example = (exampleLines || []).map(function(line) { - return ' * ' + line; - }); - - return [].concat(start, staticLine, params, [' * @example'], example, end).join('\n'); -} - -function toParams(name, lines, wrapped) { - var start = [ - "/**", - " * ", - " * Foo", - " * " - ]; - var end = [ - " * @returns Foo bar", - " */", - "function " + name + "(a, b, c) {", - "", - "}" - ]; - var staticLine = wrapped ? [] : [' * @static']; - var params = lines.map(function(line) { - return ' * @param ' + line; - }); - return [].concat(start, staticLine, params, end).join('\n'); -} - -var differenceBySource = toSource('differenceBy', [ - '{Array} array The array to inspect.', - '{...Array} [values] The values to exclude.', - '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' -], [ - "_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);", - "// → [3.1, 1.3]", - "", - "// The `_.property` iteratee shorthand.", - "_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');", - "// → [{ 'x': 2 }]" -]); - -var setParams = [ - '{Object} object The object to modify.', - '{Array|string} path The path of the property to set.', - '{*} value The value to set.' -]; - -describe('Docs FP mapping', function() { - var oldgetParams; - var oldgetExample; - - before(function() { - oldgetParams = Entry.prototype.getParams; - oldgetExample = Entry.prototype.getExample; - mapping.aryMethod[2].push('customFun'); - applyFPMapping(mapping); - }); - - after(function() { - Entry.prototype.getParams = oldgetParams; - Entry.prototype.getExample = oldgetExample; - }); - - describe('getExample', function() { - it('should reorder parameters', function() { - var entry = new Entry(differenceBySource, differenceBySource); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "_.differenceBy(Math.floor, [4.4, 2.5], [3.1, 2.2, 1.3]);", - "// → [3.1, 1.3]", - "", - "// The `_.property` iteratee shorthand.", - "_.differenceBy('x', [{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }]);", - "// → [{ 'x': 2 }]", - "```" - ].join('\n')); - }); - - it('should reorder parameters that have a special order', function() { - var example = toSource('set', setParams, [ - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set(object, 'a[0].b.c', 4);", - "_.set(object, 'x[0].y.z', 5);", - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set('a[0].b.c', 4, object);", - "_.set('x[0].y.z', 5, object);", - "```" - ].join('\n')); - }); - - it('should preserve comments', function() { - var example = toSource('set', setParams, [ - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set(object, 'a[0].b.c', 4);", - "// => 4", - "_.set(object, 'x[0].y.z', 5);", - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set('a[0].b.c', 4, object);", - "// => 4", - "_.set('x[0].y.z', 5, object);", - "```" - ].join('\n')); - }); - - it('should remove console.logs from example', function() { - var example = toSource('set', setParams, [ - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "", - "_.set(object, 'a[0].b.c', 4);", - "console.log(object.a[0].b.c);", - "// => 4", - "", - "_.set(object, 'x[0].y.z', 5);", - "console.log(object.x[0].y.z);", - "// => 5" - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "", - "_.set('a[0].b.c', 4, object);", - "// => 4", - "", - "_.set('x[0].y.z', 5, object);", - "// => 5", - "```" - ].join('\n')); - }); - - it('should merge extra arguments into an array', function() { - var example = toSource('pullAt', [ - '{Array} array The array to modify.', - '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + - ' * specified individually or in arrays.' - ], [ - "var array = [5, 10, 15, 20];", - "var evens = _.pullAt(array, 1, 3);", - "", - "console.log(array);", - "// => [5, 15]", - "", - "console.log(evens);", - "// => [10, 20]", - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "var array = [5, 10, 15, 20];", - "var evens = _.pullAt([1, 3], array);", - "", - "// => [5, 15]", - "", - "// => [10, 20]", - "```" - ].join('\n')); - }); - - it('should inject default values into optional arguments that became compulsory', function() { - var example = toSource('sampleSize', [ - '{Array|Object} collection The collection to sample.', - '{number} [n=0] The number of elements to sample.' - ], [ - "_.sampleSize([1, 2, 3]);", - "// => [3, 1]", - "", - "_.sampleSize([1, 2, 3], 4);", - "// => [2, 3, 1]" - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "_.sampleSize(0, [1, 2, 3]);", - "// => [3, 1]", - "", - "_.sampleSize(4, [1, 2, 3]);", - "// => [2, 3, 1]", - "```" - ].join('\n')); - }); - - it('should inject referenced values into optional arguments that became compulsory, ' - + 'if a parameter\'s default value references parameter (direct reference)', - function() { - var example = toSource('customFun', [ - '{Array} array Array', - '{number} [foo=array] Foo' - ], [ - "_.customFun([1, 2, 3]);", - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "_.customFun([1, 2, 3], [1, 2, 3]);", - "```" - ].join('\n')); - }); - - it('should inject referenced values into optional arguments that became compulsory, ' - + 'if a parameter\'s default value references parameter (member expression)', - function() { - var example = toSource('fill', [ - '{Array} array The array to fill.', - '{*} value The value to fill `array` with.', - '{number} [start=0] The start position.', - '{number} [end=array.length] The end position.' - ], [ - "var array = [1, 2, 3];", - "", - "_.fill(array, 'a');", - "console.log(array);", - "// => ['a', 'a', 'a']", - "", - "_.fill(Array(3), 2, 1);", - "// => [undefined, 2, 2]", - "", - "_.fill([4, 6, 8, 10], '*');", - "// => [*, '*', '*', *]" - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "var array = [1, 2, 3];", - "", - "_.fill(0, array.length, 'a', array);", - "// => ['a', 'a', 'a']", - "", - "_.fill(1, 3, 2, Array(3));", - "// => [undefined, 2, 2]", - "", - "_.fill(0, 4, '*', [4, 6, 8, 10]);", - "// => [*, '*', '*', *]", - "```" - ].join('\n')); - }); - - it('should inject default values in the middle of the arguments', function() { - var example = toSource('inRange', [ - '{number} number The number to check.', - '{number} [start=0] The start of the range.', - '{number} end The end of the range.' - ], [ - "_.inRange(4, 8);", - "// => true" - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "_.inRange(8, 0, 4);", - "// => true", - "```" - ].join('\n')); - }); - - it('should not use ignored params as default values', function() { - var example = toSource('drop', [ - '{Array} array The array to query.', - '{number} [n=1] The number of elements to drop.', - '{Object} [guard] Enables use as an iteratee for functions like `_.map`.' - ], [ - "_.drop([1, 2, 3]);", - "// => [2, 3]" - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - "```js", - "_.drop(1, [1, 2, 3]);", - "// => [2, 3]", - "```" - ].join('\n')); - }); - }); - - describe('getParams', function() { - it('should reorder arguments and remove default values', function() { - var example = toParams('differenceBy', [ - '{Array} array The array to inspect.', - '{...Array} [values] The values to exclude.', - '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Function|Object|string', 'iteratee', 'The iteratee invoked per element. '], - ['Array|Array[]', 'values', 'The values to exclude. '], - ['Array', 'array', 'The array to inspect. '] - ]); - }); - - it('should reorder arguments that have a special order', function() { - var example = toParams('set', [ - '{Object} object The object to modify.', - '{Array|string} path The path of the property to set.', - '{*} value The value to set.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Array|string', 'path', 'The path of the property to set. '], - ['*', 'value', 'The value to set. '], - ['Object', 'object', 'The object to modify. '], - ]); - }); - - it('should transform rest arguments into an array', function() { - var example = toParams('pullAt', [ - '{Array} array The array to modify.', - '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + - ' * specified individually or in arrays.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - // TODO Remove this line in favor of the commented one. - // Is linked to a docdown (https://github.com/jdalton/docdown/pull/37) - // that does not handle parens in the arguments well - ['((number|number)|((number|number)[]', 'indexes', 'The indexes of elements to remove, specified individually or in arrays. '], - // ['number|number[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], - ['Array', 'array', 'The array to modify. '], - ]); - }); - }); - - it('should duplicate and de-restify "rest" parameters if there are less parameters than cap', function() { - var example = toParams('intersectionWith', [ - '{...Array} [arrays] The arrays to inspect.', - '{Function} [comparator] The comparator invoked per element.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Function', 'comparator', 'The comparator invoked per element. '], - ['Array', 'arrays', 'The arrays to inspect. '], - ['Array', 'arrays', 'The arrays to inspect. '] - ]); - }); - - it('should consider method to have an ary of `ary - 1` when capped and wrapped', function() { - var wrapped = true; - var example = toParams('flatMap', [ - '{Array} array The array to iterate over.', - '{Function|Object|string} [iteratee=_.identity] The function invoked per iteration.' - ], wrapped); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Function|Object|string', 'iteratee', 'The function invoked per iteration. '] - ]); - }); - - it('should remove arguments ignored because of capping', function() { - var example = toParams('includes', [ - '{Array|Object|string} collection The collection to search.', - '{*} value The value to search for.', - '{number} [fromIndex=0] The index to search from.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['*', 'value', 'The value to search for. '], - ['Array|Object|string', 'collection', 'The collection to search. '] - ]); - }); -}); diff --git a/package.json b/package.json index 6066accfc2..a757b2d06a 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,8 @@ "style:main": "jscs lodash.js", "style:perf": "jscs perf/*.js perf/**/*.js", "style:test": "jscs test/*.js test/**/*.js", - "test": "npm run test:main && npm run test:fp", + "test": "npm run test:main && npm run test:fp && npm run test:docs", + "test:docs": "node test/test-fp-doc", "test:fp": "node test/test-fp", "test:main": "node test/test" } diff --git a/test/test-fp-doc.js b/test/test-fp-doc.js new file mode 100644 index 0000000000..a1569c96bd --- /dev/null +++ b/test/test-fp-doc.js @@ -0,0 +1,508 @@ +;(function() { + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; + + /** Used as a reference to the global object. */ + var root = (typeof global == 'object' && global) || this; + + var phantom = root.phantom, + amd = root.define && define.amd, + document = !phantom && root.document, + noop = function() {}, + argv = root.process && process.argv; + + /** Use a single "load" function. */ + var load = (!amd && typeof require == 'function') + ? require + : noop; + + /** The unit testing framework. */ + var QUnit = root.QUnit || (root.QUnit = ( + QUnit = load('../node_modules/qunitjs/qunit/qunit.js') || root.QUnit, + QUnit = QUnit.QUnit || QUnit + )); + + /** Load stable Lodash and QUnit Extras. */ + var _ = root._ || load('../lodash.js'); + if (_) { + _ = _.runInContext(root); + } + var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js'); + if (QUnitExtras) { + QUnitExtras.runInContext(root); + } + + var mapping = root.mapping || load('../fp/_mapping.js'), + applyFPMapping = load('../lib/doc/apply-fp-mapping'), + Entry = load('docdown/lib/entry'); + + /*--------------------------------------------------------------------------*/ + + function toEntry(name, paramLines, exampleLines, attachedToPrototype) { + var start = [ + '/**', + ' * ', + ' * Foo', + ' * ' + ]; + var end = [ + ' */', + 'function ' + name + '(a, b, c) {', + '', + '}' + ]; + var staticLine = attachedToPrototype ? [] : [' * @static']; + var params = paramLines.map(function(line) { + return ' * @param ' + line; + }); + var example = (exampleLines || []).map(function(line) { + return ' * ' + line; + }); + + return [].concat(start, staticLine, params, [' * @example'], example, end).join('\n'); + } + + var differenceBySource = toEntry('differenceBy', [ + '{Array} array The array to inspect.', + '{...Array} [values] The values to exclude.', + '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' + ], [ + '_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);', + '// → [3.1, 1.3]', + '', + '// The `_.property` iteratee shorthand.', + "_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');", + "// → [{ 'x': 2 }]" + ]); + + var setParams = [ + '{Object} object The object to modify.', + '{Array|string} path The path of the property to set.', + '{*} value The value to set.' + ]; + + /*--------------------------------------------------------------------------*/ + + if (argv) { + console.log('Running doc generation tests.'); + } + + mapping.aryMethod[2].push('customFun'); + applyFPMapping(mapping); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('getExample'); + + (function() { + QUnit.test('should reorder parameters', function(assert) { + assert.expect(1); + + var entry = new Entry(differenceBySource, differenceBySource); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + '_.differenceBy(Math.floor, [4.4, 2.5], [3.1, 2.2, 1.3]);', + '// → [3.1, 1.3]', + '', + '// The `_.property` iteratee shorthand.', + "_.differenceBy('x', [{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }]);", + "// → [{ 'x': 2 }]", + '```' + ].join('\n')); + }); + + QUnit.test('should reorder parameters that have a special order', function(assert) { + assert.expect(1); + + var example = toEntry('set', setParams, [ + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set(object, 'a[0].b.c', 4);", + "_.set(object, 'x[0].y.z', 5);", + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set('a[0].b.c', 4, object);", + "_.set('x[0].y.z', 5, object);", + '```' + ].join('\n')); + }); + + QUnit.test('should preserve comments', function(assert) { + assert.expect(1); + + var example = toEntry('set', setParams, [ + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set(object, 'a[0].b.c', 4);", + '// => 4', + "_.set(object, 'x[0].y.z', 5);", + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + "_.set('a[0].b.c', 4, object);", + '// => 4', + "_.set('x[0].y.z', 5, object);", + '```' + ].join('\n')); + }); + + QUnit.test('should remove console.logs from example', function(assert) { + assert.expect(1); + + var example = toEntry('set', setParams, [ + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + '', + "_.set(object, 'a[0].b.c', 4);", + 'console.log(object.a[0].b.c);', + '// => 4', + '', + "_.set(object, 'x[0].y.z', 5);", + 'console.log(object.x[0].y.z);', + '// => 5' + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + "var object = { 'a': [{ 'b': { 'c': 3 } }] };", + '', + "_.set('a[0].b.c', 4, object);", + '// => 4', + '', + "_.set('x[0].y.z', 5, object);", + '// => 5', + '```' + ].join('\n')); + }); + + QUnit.test('should merge extra arguments into an array', function(assert) { + assert.expect(1); + + var example = toEntry('pullAt', [ + '{Array} array The array to modify.', + '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + + ' * specified individually or in arrays.' + ], [ + 'var array = [5, 10, 15, 20];', + 'var evens = _.pullAt(array, 1, 3);', + '', + 'console.log(array);', + '// => [5, 15]', + '', + 'console.log(evens);', + '// => [10, 20]' + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + 'var array = [5, 10, 15, 20];', + 'var evens = _.pullAt([1, 3], array);', + '', + '// => [5, 15]', + '', + '// => [10, 20]', + '```' + ].join('\n')); + }); + + QUnit.test('should inject default values into optional arguments that became compulsory', function(assert) { + assert.expect(1); + + var example = toEntry('sampleSize', [ + '{Array|Object} collection The collection to sample.', + '{number} [n=0] The number of elements to sample.' + ], [ + '_.sampleSize([1, 2, 3]);', + '// => [3, 1]', + '', + '_.sampleSize([1, 2, 3], 4);', + '// => [2, 3, 1]' + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + '_.sampleSize(0, [1, 2, 3]);', + '// => [3, 1]', + '', + '_.sampleSize(4, [1, 2, 3]);', + '// => [2, 3, 1]', + '```' + ].join('\n')); + }); + + QUnit.test('should inject referenced values into optional arguments that became compulsory, ' + + + 'if a parameter\'s default value references parameter (direct reference)', + function(assert) { + assert.expect(1); + + var example = toEntry('customFun', [ + '{Array} array Array', + '{number} [foo=array] Foo' + ], [ + '_.customFun([1, 2, 3]);', + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + '_.customFun([1, 2, 3], [1, 2, 3]);', + '```' + ].join('\n')); + }); + + QUnit.test('should inject referenced values into optional arguments that became compulsory, ' + + 'if a parameter\'s default value references parameter (member expression)', + function(assert) { + assert.expect(1); + + var example = toEntry('fill', [ + '{Array} array The array to fill.', + '{*} value The value to fill `array` with.', + '{number} [start=0] The start position.', + '{number} [end=array.length] The end position.' + ], [ + 'var array = [1, 2, 3];', + '', + "_.fill(array, 'a');", + 'console.log(array);', + "// => ['a', 'a', 'a']", + '', + '_.fill(Array(3), 2, 1);', + '// => [undefined, 2, 2]', + '', + "_.fill([4, 6, 8, 10], '*');", + "// => [*, '*', '*', *]" + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + 'var array = [1, 2, 3];', + '', + "_.fill(0, array.length, 'a', array);", + "// => ['a', 'a', 'a']", + '', + '_.fill(1, 3, 2, Array(3));', + '// => [undefined, 2, 2]', + '', + "_.fill(0, 4, '*', [4, 6, 8, 10]);", + "// => [*, '*', '*', *]", + '```' + ].join('\n')); + }); + + QUnit.test('should inject default values in the middle of the arguments', function(assert) { + assert.expect(1); + + var example = toEntry('inRange', [ + '{number} number The number to check.', + '{number} [start=0] The start of the range.', + '{number} end The end of the range.' + ], [ + '_.inRange(4, 8);', + '// => true' + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + '_.inRange(8, 0, 4);', + '// => true', + '```' + ].join('\n')); + }); + + QUnit.test('should not use ignored params as default values', function(assert) { + assert.expect(1); + + var example = toEntry('drop', [ + '{Array} array The array to query.', + '{number} [n=1] The number of elements to drop.', + '{Object} [guard] Enables use as an iteratee for functions like `_.map`.' + ], [ + '_.drop([1, 2, 3]);', + '// => [2, 3]' + ]); + var entry = new Entry(example, example); + + var actual = entry.getExample(); + + assert.equal(actual, [ + '```js', + '_.drop(1, [1, 2, 3]);', + '// => [2, 3]', + '```' + ].join('\n')); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('getParams'); + + (function() { + QUnit.test('should reorder arguments and remove default values', function(assert) { + assert.expect(1); + + var example = toEntry('differenceBy', [ + '{Array} array The array to inspect.', + '{...Array} [values] The values to exclude.', + '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Function|Object|string', 'iteratee', 'The iteratee invoked per element. '], + ['Array|Array[]', 'values', 'The values to exclude. '], + ['Array', 'array', 'The array to inspect. '] + ]); + }); + + QUnit.test('should reorder arguments that have a special order', function(assert) { + assert.expect(1); + + var example = toEntry('set', [ + '{Object} object The object to modify.', + '{Array|string} path The path of the property to set.', + '{*} value The value to set.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Array|string', 'path', 'The path of the property to set. '], + ['*', 'value', 'The value to set. '], + ['Object', 'object', 'The object to modify. '], + ]); + }); + + QUnit.test('should transform rest arguments into an array', function(assert) { + assert.expect(1); + + var example = toEntry('pullAt', [ + '{Array} array The array to modify.', + '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + + ' * specified individually or in arrays.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + // TODO Remove this line in favor of the commented one. + // Is linked to a docdown issue (https://github.com/jdalton/docdown/pull/37) + // that does not handle parens in the arguments well + ['((number|number)|((number|number)[]', 'indexes', 'The indexes of elements to remove, specified individually or in arrays. '], + // ['number|number[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], + ['Array', 'array', 'The array to modify. '], + ]); + }); + + QUnit.test('should duplicate and de-restify "rest" parameters if there are less parameters than cap', function(assert) { + assert.expect(1); + + var example = toEntry('intersectionWith', [ + '{...Array} [arrays] The arrays to inspect.', + '{Function} [comparator] The comparator invoked per element.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Function', 'comparator', 'The comparator invoked per element. '], + ['Array', 'arrays', 'The arrays to inspect. '], + ['Array', 'arrays', 'The arrays to inspect. '] + ]); + }); + + QUnit.test('should consider method to have an ary of `ary - 1` when capped and wrapped', function(assert) { + assert.expect(1); + + var wrapped = true; + var example = toEntry('flatMap', [ + '{Array} array The array to iterate over.', + '{Function|Object|string} [iteratee=_.identity] The function invoked per iteration.' + ], [], wrapped); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['Function|Object|string', 'iteratee', 'The function invoked per iteration. '] + ]); + }); + + QUnit.test('should remove arguments ignored because of capping (includes)', function(assert) { + assert.expect(1); + + var example = toEntry('includes', [ + '{Array|Object|string} collection The collection to search.', + '{*} value The value to search for.', + '{number} [fromIndex=0] The index to search from.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['*', 'value', 'The value to search for. '], + ['Array|Object|string', 'collection', 'The collection to search. '] + ]); + }); + + QUnit.test('should remove arguments ignored because of capping (trim)', function(assert) { + assert.expect(1); + + var example = toEntry('trim', [ + "{string} [string=''] The string to trim.", + '{string} [chars=whitespace] The characters to trim.' + ]); + var entry = new Entry(example, example); + + var actual = entry.getParams(); + + assert.deepEqual(actual, [ + ['string', 'string', 'The string to trim. '] + ]); + }); + }()); + + QUnit.config.asyncRetries = 10; + QUnit.config.hidepassed = true; + + if (!document) { + QUnit.config.noglobals = true; + QUnit.load(); + } +}.call(this)); From 02bea6534c10494b6a199fffb8407cd8cd01adef Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Wed, 10 Feb 2016 01:12:36 +0100 Subject: [PATCH 15/79] fp docs - Remove notes about mutation in description. --- lib/doc/apply-fp-mapping/description.js | 39 +++++++++++++ lib/doc/apply-fp-mapping/index.js | 2 + test/test-fp-doc.js | 78 ++++++++++++++++++++++++- 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 lib/doc/apply-fp-mapping/description.js diff --git a/lib/doc/apply-fp-mapping/description.js b/lib/doc/apply-fp-mapping/description.js new file mode 100644 index 0000000000..f6b4f1bdd4 --- /dev/null +++ b/lib/doc/apply-fp-mapping/description.js @@ -0,0 +1,39 @@ +var _ = require('lodash'), + j = require('jscodeshift'), + Entry = require('docdown/lib/entry'), + common = require('./common'); + +var baseGetDesc = Entry.prototype.getDesc; + +var lineBreaksRegex = /\n?$/g; + +/** + * Return the `description` of the entry, only without the possible note about mutation. + * + * @returns {Function} Updated description. + */ +function getReorderedExample() { + var lines = baseGetDesc.call(this).split('\n'); + + var indexOfLine = _.findIndex(lines, function(line) { + return _.includes(line, 'mutate'); + }); + + if (indexOfLine === -1) { + return lines.join('\n'); + } + + var linesToDelete = 1; + while (indexOfLine + linesToDelete < lines.length && + !lines[indexOfLine + linesToDelete].startsWith(' Date: Tue, 9 Feb 2016 20:10:21 -0500 Subject: [PATCH 16/79] Fix FP rearg for `_.zipWith` and `_.inRange`. --- fp/_mapping.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/fp/_mapping.js b/fp/_mapping.js index 75f0babaa6..42d7c993c6 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -80,7 +80,7 @@ exports.aryMethod = { /** Used to map ary to rearg configs. */ exports.aryRearg = { 2: [1, 0], - 3: [2, 1, 0], + 3: [2, 0, 1], 4: [3, 2, 0, 1] }; @@ -138,14 +138,13 @@ exports.iterateeRearg = { exports.methodRearg = { 'assignInWith': [1, 2, 0], 'assignWith': [1, 2, 0], - 'clamp': [2, 0, 1], + 'getOr': [2, 1, 0], + 'isMatchWith': [2, 1, 0], 'mergeWith': [1, 2, 0], - 'reduce': [2, 0, 1], - 'reduceRight': [2, 0, 1], - 'set': [2, 0, 1], + 'pullAllBy': [2, 1, 0], 'setWith': [3, 1, 2, 0], - 'slice': [2, 0, 1], - 'transform': [2, 0, 1] + 'sortedIndexBy': [2, 1, 0], + 'sortedLastIndexBy': [2, 1, 0] }; /** Used to map method names to spread configs. */ From 046470a8db09178fbe5071ef1f1e7507cca4241d Mon Sep 17 00:00:00 2001 From: Michael Morgan Date: Mon, 8 Feb 2016 17:09:13 -0600 Subject: [PATCH 17/79] Added `_.flattenDepth` for variable-depth flatten. --- fp/_mapping.js | 6 ++-- lodash.js | 88 ++++++++++++++++++++++++++++++++------------------ test/test.js | 24 ++++++++------ 3 files changed, 75 insertions(+), 43 deletions(-) diff --git a/fp/_mapping.js b/fp/_mapping.js index 42d7c993c6..8975c1dd63 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -50,9 +50,9 @@ exports.aryMethod = { 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', - 'findLastKey', 'flatMap', 'forEach', 'forEachRight', 'forIn', 'forInRight', - 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', - 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', + 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', + 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', + 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', diff --git a/lodash.js b/lodash.js index c824f8bbf6..369ba54507 100644 --- a/lodash.js +++ b/lodash.js @@ -1399,23 +1399,23 @@ * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`, * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, - * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`, - * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, - * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, - * `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, - * `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, - * `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, - * `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`, - * `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`, - * `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, - * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, - * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, - * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, - * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, - * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, - * `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, - * `zipObjectDeep`, and `zipWith` + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, + * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, + * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, + * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, + * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, + * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, + * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, + * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`, + * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, + * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, + * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, + * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`, + * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, + * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, @@ -2494,12 +2494,14 @@ * * @private * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. + * @param {number} [depth=1] The maximum recursion depth. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict, result) { + function baseFlatten(array, depth, isStrict, result) { + depth = depth === undefined ? 1 : depth; + result || (result = []); var index = -1, @@ -2509,9 +2511,9 @@ var value = array[index]; if (isArrayLikeObject(value) && (isStrict || isArray(value) || isArguments(value))) { - if (isDeep) { + if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, isDeep, isStrict, result); + baseFlatten(value, depth - 1, isStrict, result); } else { arrayPush(result, value); } @@ -5475,7 +5477,7 @@ */ var difference = rest(function(array, values) { return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, false, true)) + ? baseDifference(array, baseFlatten(values, 1, true)) : []; }); @@ -5506,7 +5508,7 @@ iteratee = undefined; } return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee)) + ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee)) : []; }); @@ -5535,7 +5537,7 @@ comparator = undefined; } return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) : []; }); @@ -5814,7 +5816,7 @@ * @returns {Array} Returns the new flattened array. * @example * - * _.flatten([1, [2, 3, [4]]]); + * _.flatten([1, 2, [3, [4]]]); * // => [1, 2, 3, [4]] */ function flatten(array) { @@ -5832,12 +5834,35 @@ * @returns {Array} Returns the new flattened array. * @example * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] + * _.flattenDeep([1, [2, [3, [[4]]], 5]]); + * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {number} depth The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDepth([1, [2, [3, [4]], 5]], 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth([1, [2, [3, [4]], 5]], 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + depth = toInteger(depth); + var length = array ? array.length : 0; + return length ? (depth >= 1 ? baseFlatten(array, depth) : copyArray(array)) : []; } /** @@ -6677,7 +6702,7 @@ * // => [2, 1, 4] */ var union = rest(function(arrays) { - return baseUniq(baseFlatten(arrays, false, true)); + return baseUniq(baseFlatten(arrays, 1, true)); }); /** @@ -6705,7 +6730,7 @@ if (isArrayLikeObject(iteratee)) { iteratee = undefined; } - return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee)); + return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee)); }); /** @@ -6732,7 +6757,7 @@ if (isArrayLikeObject(comparator)) { comparator = undefined; } - return baseUniq(baseFlatten(arrays, false, true), undefined, comparator); + return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator); }); /** @@ -14208,6 +14233,7 @@ lodash.flatMap = flatMap; lodash.flatten = flatten; lodash.flattenDeep = flattenDeep; + lodash.flattenDepth = flattenDepth; lodash.flip = flip; lodash.flow = flow; lodash.flowRight = flowRight; diff --git a/test/test.js b/test/test.js index 5d3cea8d9e..b32291b4a5 100644 --- a/test/test.js +++ b/test/test.js @@ -5620,31 +5620,37 @@ }); QUnit.test('should work with empty arrays', function(assert) { - assert.expect(2); + assert.expect(3); var array = [[], [[]], [[], [[[]]]]]; assert.deepEqual(_.flatten(array), [[], [], [[[]]]]); assert.deepEqual(_.flattenDeep(array), []); + assert.deepEqual(_.flattenDepth(array, 2), [[[]]]) }); QUnit.test('should support flattening of nested arrays', function(assert) { - assert.expect(2); + assert.expect(4); - var array = [1, [2, 3], 4, [[5]]]; + var array = [1, [[2, 3], 4, [[[5]]]]]; - assert.deepEqual(_.flatten(array), [1, 2, 3, 4, [5]]); + assert.deepEqual(_.flatten(array), [1, [2, 3], 4, [[[5]]]]); assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]); + assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 4, [[5]]]); + assert.deepEqual(_.flattenDepth(array, 3), [1, 2, 3, 4, [5]]); }); QUnit.test('should return an empty array for non array-like objects', function(assert) { - assert.expect(3); + assert.expect(5); + var nonArray = { 'a': 1 }; var expected = []; - assert.deepEqual(_.flatten({ 'a': 1 }), expected); - assert.deepEqual(_.flatten({ 'a': 1 }, true), expected); - assert.deepEqual(_.flattenDeep({ 'a': 1 }), expected); + assert.deepEqual(_.flatten(nonArray), expected); + assert.deepEqual(_.flatten(nonArray, true), expected); + assert.deepEqual(_.flattenDeep(nonArray), expected); + assert.deepEqual(_.flattenDepth(nonArray, 2), expected); + assert.deepEqual(_.flattenDepth(nonArray, 0), expected); }); QUnit.test('should return a wrapped value when chaining', function(assert) { @@ -24035,7 +24041,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(295); + assert.expect(296); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray); From 08c7bf3c8506b05f4ea1b7370addc13c95203672 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Wed, 10 Feb 2016 01:22:39 +0100 Subject: [PATCH 18/79] Fix code style error and doc nit. [ci skip] --- lodash.js | 2 +- test/test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lodash.js b/lodash.js index 369ba54507..899730efbc 100644 --- a/lodash.js +++ b/lodash.js @@ -11528,7 +11528,7 @@ * @category Object * @param {Object} object The source object. * @param {...(string|string[])} [props] The property names to omit, specified - * individually or in arrays.. + * individually or in arrays. * @returns {Object} Returns the new object. * @example * diff --git a/test/test.js b/test/test.js index b32291b4a5..acd7d90b76 100644 --- a/test/test.js +++ b/test/test.js @@ -5626,7 +5626,7 @@ assert.deepEqual(_.flatten(array), [[], [], [[[]]]]); assert.deepEqual(_.flattenDeep(array), []); - assert.deepEqual(_.flattenDepth(array, 2), [[[]]]) + assert.deepEqual(_.flattenDepth(array, 2), [[[]]]); }); QUnit.test('should support flattening of nested arrays', function(assert) { From c91196d240d323e439bedd85d9844c464ad5187a Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Tue, 9 Feb 2016 18:29:43 -0800 Subject: [PATCH 19/79] Run style checks before publishing. --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a757b2d06a..8de3747a66 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "doc:fp": "node lib/doc/build --fp github", "doc:fp:site": "node lib/doc/build --fp site", "doc:site": "node lib/doc/build site", + "prepublish": "npm run style", "pretest": "npm run build", "style": "npm run style:main & npm run style:fp & npm run style:perf & npm run style:test", "style:fp": "jscs fp/*.js lib/**/*.js", From e9edc06aaf257941b49b1bdb857cbad650866bf3 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Tue, 9 Feb 2016 21:56:49 -0800 Subject: [PATCH 20/79] Enable `convert` to work when given lodash and `options`. --- fp/_baseConvert.js | 11 ++++---- fp/_convertBrowser.js | 2 +- test/test-fp.js | 60 ++++++++++++++++++++++++------------------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index cf742defed..3dd940401a 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -18,12 +18,13 @@ var mapping = require('./_mapping'), * @returns {Function|Object} Returns the converted function or object. */ function baseConvert(util, name, func, options) { - options || (options = {}); - - if (typeof func != 'function') { + var isLib = typeof name == 'function'; + if (isLib) { + options = func; func = name; name = undefined; } + options || (options = {}); if (func == null) { throw new TypeError; } @@ -37,8 +38,6 @@ function baseConvert(util, name, func, options) { var forceRearg = ('rearg' in options) && options.rearg; - var isLib = name === undefined && typeof func.VERSION == 'string'; - var _ = isLib ? func : { 'ary': util.ary, 'cloneDeep': util.cloneDeep, @@ -180,7 +179,7 @@ function baseConvert(util, name, func, options) { }, 'runInContext': function(runInContext) { return function(context) { - return baseConvert(util, runInContext(context), undefined, options); + return baseConvert(util, runInContext(context), options); }; } }; diff --git a/fp/_convertBrowser.js b/fp/_convertBrowser.js index 0e69e66cda..fd74897816 100644 --- a/fp/_convertBrowser.js +++ b/fp/_convertBrowser.js @@ -8,7 +8,7 @@ var baseConvert = require('./_baseConvert'); * @returns {Function} Returns the converted `lodash`. */ function browserConvert(lodash, options) { - return baseConvert(lodash, lodash, undefined, options); + return baseConvert(lodash, lodash, options); } module.exports = browserConvert; diff --git a/test/test-fp.js b/test/test-fp.js index 654652928f..c4345340e4 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -52,7 +52,8 @@ }; } return function(name, func, options) { - if (typeof func != 'function') { + if (typeof name == 'function') { + options = func; func = name; name = undefined; } @@ -90,18 +91,19 @@ QUnit.module('convert'); (function() { + var allFalseOptions = { + 'cap': false, + 'curry': false, + 'fixed': false, + 'immutable': false, + 'rearg': false + }; + QUnit.test('should accept an `options` argument', function(assert) { assert.expect(3); - var array = [1, 2, 3, 4]; - - var remove = convert('remove', _.remove, { - 'cap': false, - 'curry': false, - 'fixed': false, - 'immutable': false, - 'rearg': false - }); + var array = [1, 2, 3, 4], + remove = convert('remove', _.remove, allFalseOptions); var actual = remove(array, function(n, index) { return index % 2 == 0; @@ -150,9 +152,7 @@ QUnit.test('should respect the `cap` option', function(assert) { assert.expect(1); - var iteratee = convert('iteratee', _.iteratee, { - 'cap': false - }); + var iteratee = convert('iteratee', _.iteratee, { 'cap': false }); var func = iteratee(function(a, b, c) { return [a, b, c]; @@ -164,9 +164,7 @@ QUnit.test('should respect the `rearg` option', function(assert) { assert.expect(1); - var add = convert('add', _.add, { - 'rearg': true - }); + var add = convert('add', _.add, { 'rearg': true }); assert.strictEqual(add('2')('1'), '12'); }); @@ -174,23 +172,31 @@ QUnit.test('should use `options` in `runInContext`', function(assert) { assert.expect(3); - var runInContext = convert('runInContext', _.runInContext, { - 'cap': false, - 'curry': false, - 'fixed': false, - 'immutable': false, - 'rearg': false + var array = [1, 2, 3, 4], + runInContext = convert('runInContext', _.runInContext, allFalseOptions), + lodash = runInContext(); + + var actual = lodash.remove(array, function(n, index) { + return index % 2 == 0; }); + assert.deepEqual(array, [2, 4]); + assert.deepEqual(actual, [1, 3]); + assert.deepEqual(lodash.remove(), []); + }); + + QUnit.test('should work when given lodash and `options`', function(assert) { + assert.expect(3); + var array = [1, 2, 3, 4], - lodash = runInContext(); + lodash = convert(_.runInContext(), allFalseOptions); - var actual = lodash.remove(array, function(n) { - return n % 2 == 0; + var actual = lodash.remove(array, function(n, index) { + return index % 2 == 0; }); - assert.deepEqual(array, [1, 3]); - assert.deepEqual(actual, [2, 4]); + assert.deepEqual(array, [2, 4]); + assert.deepEqual(actual, [1, 3]); assert.deepEqual(lodash.remove(), []); }); }()); From ba32bf3b8d1290818625246726b1fbdc8d049d54 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Feb 2016 00:14:10 -0800 Subject: [PATCH 21/79] Cleanup flatten methods and add more `flattenDepth` tests. --- lodash.js | 31 +++++++++-------- test/test.js | 95 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 73 insertions(+), 53 deletions(-) diff --git a/lodash.js b/lodash.js index 899730efbc..0dbf498512 100644 --- a/lodash.js +++ b/lodash.js @@ -2494,14 +2494,12 @@ * * @private * @param {Array} array The array to flatten. - * @param {number} [depth=1] The maximum recursion depth. + * @param {number} depth The maximum recursion depth. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ function baseFlatten(array, depth, isStrict, result) { - depth = depth === undefined ? 1 : depth; - result || (result = []); var index = -1, @@ -5807,7 +5805,7 @@ } /** - * Flattens `array` a single level. + * Flattens `array` a single level deep. * * @static * @memberOf _ @@ -5816,8 +5814,8 @@ * @returns {Array} Returns the new flattened array. * @example * - * _.flatten([1, 2, [3, [4]]]); - * // => [1, 2, 3, [4]] + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] */ function flatten(array) { var length = array ? array.length : 0; @@ -5825,16 +5823,16 @@ } /** - * This method is like `_.flatten` except that it recursively flattens `array`. + * Recursively flattens `array`. * * @static * @memberOf _ * @category Array - * @param {Array} array The array to recursively flatten. + * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * - * _.flattenDeep([1, [2, [3, [[4]]], 5]]); + * _.flattenDeep([1, [2, [3, [4]], 5]]); * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { @@ -5849,20 +5847,25 @@ * @memberOf _ * @category Array * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. + * @param {number} [depth=1] The maximum recursion depth. * @returns {Array} Returns the new flattened array. * @example * - * _.flattenDepth([1, [2, [3, [4]], 5]], 1); + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); * // => [1, 2, [3, [4]], 5] * - * _.flattenDepth([1, [2, [3, [4]], 5]], 2); + * _.flattenDepth(array, 2); * // => [1, 2, 3, [4], 5] */ function flattenDepth(array, depth) { - depth = toInteger(depth); var length = array ? array.length : 0; - return length ? (depth >= 1 ? baseFlatten(array, depth) : copyArray(array)) : []; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return depth < 1 ? copyArray(array) : baseFlatten(array, depth); } /** diff --git a/test/test.js b/test/test.js index acd7d90b76..5a3ae56abb 100644 --- a/test/test.js +++ b/test/test.js @@ -5559,25 +5559,48 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('flatten methods'); + QUnit.module('lodash.flattenDepth'); (function() { - var args = arguments; + var array = [1, [2, [3, [4]], 5]]; - QUnit.test('should perform a shallow flatten', function(assert) { + QUnit.test('should use a default `depth` of `1`', function(assert) { assert.expect(1); - var array = [[['a']], [['b']]]; - assert.deepEqual(_.flatten(array), [['a'], ['b']]); + assert.deepEqual(_.flattenDepth(array), [1, 2, [3, [4]], 5]); }); - QUnit.test('should flatten `arguments` objects', function(assert) { + QUnit.test('should treat a `depth` of < `1` as a shallow clone', function(assert) { assert.expect(2); + lodashStable.each([-1, 0], function(depth) { + assert.deepEqual(_.flattenDepth(array, depth), [1, [2, [3, [4]], 5]]); + }); + }); + + QUnit.test('should coerce `depth` to an integer', function(assert) { + assert.expect(1); + + assert.deepEqual(_.flattenDepth(array, 2.2), [1, 2, 3, [4], 5]); + }); + }()); + + /*--------------------------------------------------------------------------*/ + + QUnit.module('flatten methods'); + + (function() { + var args = arguments, + array = [1, [2, [3, [4]], 5]]; + + QUnit.test('should flatten `arguments` objects', function(assert) { + assert.expect(3); + var array = [args, [args]]; assert.deepEqual(_.flatten(array), [1, 2, 3, args]); assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 1, 2, 3]); + assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 1, 2, 3]); }); QUnit.test('should treat sparse arrays as dense', function(assert) { @@ -5588,7 +5611,7 @@ expected.push(undefined, undefined, undefined); - lodashStable.each([_.flatten(array), _.flatten(array, true), _.flattenDeep(array)], function(actual) { + lodashStable.each([_.flatten(array), _.flattenDeep(array), _.flattenDepth(array)], function(actual) { assert.deepEqual(actual, expected); assert.ok('4' in actual); }); @@ -5597,24 +5620,18 @@ QUnit.test('should work with extremely large arrays', function(assert) { assert.expect(3); - // Test in modern browsers only to avoid browser hangs. lodashStable.times(3, function(index) { - if (freeze) { - var expected = Array(5e5); - - try { - if (index) { - var actual = actual == 1 ? _.flatten([expected], true) : _.flattenDeep([expected]); - } else { - actual = _.flatten(expected); - } - assert.deepEqual(actual, expected); - } catch (e) { - assert.ok(false, e.message); + var expected = Array(5e5); + try { + var func = _.flatten; + if (index == 1) { + func = _.flattenDeep; + } else if (index == 2) { + func = _.flattenDepth; } - } - else { - skipTest(assert); + assert.deepEqual(func([expected]), expected); + } catch (e) { + assert.ok(false, e.message); } }); }); @@ -5630,46 +5647,46 @@ }); QUnit.test('should support flattening of nested arrays', function(assert) { - assert.expect(4); - - var array = [1, [[2, 3], 4, [[[5]]]]]; + assert.expect(3); - assert.deepEqual(_.flatten(array), [1, [2, 3], 4, [[[5]]]]); + assert.deepEqual(_.flatten(array), [1, 2, [3, [4]], 5]); assert.deepEqual(_.flattenDeep(array), [1, 2, 3, 4, 5]); - assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, 4, [[5]]]); - assert.deepEqual(_.flattenDepth(array, 3), [1, 2, 3, 4, [5]]); + assert.deepEqual(_.flattenDepth(array, 2), [1, 2, 3, [4], 5]); }); QUnit.test('should return an empty array for non array-like objects', function(assert) { - assert.expect(5); + assert.expect(3); - var nonArray = { 'a': 1 }; - var expected = []; + var expected = [], + nonArray = { 'a': 1 }; assert.deepEqual(_.flatten(nonArray), expected); - assert.deepEqual(_.flatten(nonArray, true), expected); assert.deepEqual(_.flattenDeep(nonArray), expected); assert.deepEqual(_.flattenDepth(nonArray, 2), expected); - assert.deepEqual(_.flattenDepth(nonArray, 0), expected); }); QUnit.test('should return a wrapped value when chaining', function(assert) { - assert.expect(4); + assert.expect(6); if (!isNpm) { - var wrapped = _([1, [2], [3, [4]]]), + var wrapped = _(array), actual = wrapped.flatten(); assert.ok(actual instanceof _); - assert.deepEqual(actual.value(), [1, 2, 3, [4]]); + assert.deepEqual(actual.value(), [1, 2, [3, [4]], 5]); actual = wrapped.flattenDeep(); assert.ok(actual instanceof _); - assert.deepEqual(actual.value(), [1, 2, 3, 4]); + assert.deepEqual(actual.value(), [1, 2, 3, 4, 5]); + + actual = wrapped.flattenDepth(2); + + assert.ok(actual instanceof _); + assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]); } else { - skipTest(assert, 4); + skipTest(assert, 6); } }); }(1, 2, 3)); From 40bb035b093e600732fbbb3693373dd9220543f1 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Feb 2016 00:15:08 -0800 Subject: [PATCH 22/79] Minor label cleanup. --- test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index 5a3ae56abb..70fae59217 100644 --- a/test/test.js +++ b/test/test.js @@ -6722,7 +6722,7 @@ assert.strictEqual(_.gt('def', 'abc'), true); }); - QUnit.test('should return `false` if `value` is less than or equal to `other`', function(assert) { + QUnit.test('should return `false` if `value` is <= `other`', function(assert) { assert.expect(4); assert.strictEqual(_.gt(1, 3), false); @@ -12202,7 +12202,7 @@ QUnit.module('lodash.lte'); (function() { - QUnit.test('should return `true` if `value` is less than or equal to `other`', function(assert) { + QUnit.test('should return `true` if `value` is <= `other`', function(assert) { assert.expect(4); assert.strictEqual(_.lte(1, 3), true); From 3014f20b6c837111a1a2412374fe53e6d3d96b0f Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Feb 2016 00:43:03 -0800 Subject: [PATCH 23/79] Remove `copyArray` dep from `_.flattenDepth`. --- lodash.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lodash.js b/lodash.js index 0dbf498512..9e3882309c 100644 --- a/lodash.js +++ b/lodash.js @@ -2507,7 +2507,7 @@ while (++index < length) { var value = array[index]; - if (isArrayLikeObject(value) && + if (depth > 0 && isArrayLikeObject(value) && (isStrict || isArray(value) || isArguments(value))) { if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). @@ -4173,7 +4173,7 @@ */ function createFlow(fromRight) { return rest(function(funcs) { - funcs = baseFlatten(funcs); + funcs = baseFlatten(funcs, 1); var length = funcs.length, index = length, @@ -4313,7 +4313,7 @@ */ function createOver(arrayFunc) { return rest(function(iteratees) { - iteratees = arrayMap(baseFlatten(iteratees), getIteratee()); + iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee()); return rest(function(args) { var thisArg = this; return arrayFunc(iteratees, function(iteratee) { @@ -5453,7 +5453,7 @@ if (!isArray(array)) { array = array == null ? [] : [Object(array)]; } - values = baseFlatten(values); + values = baseFlatten(values, 1); return arrayConcat(array, values); }); @@ -5819,7 +5819,7 @@ */ function flatten(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array) : []; + return length ? baseFlatten(array, 1) : []; } /** @@ -5865,7 +5865,7 @@ return []; } depth = depth === undefined ? 1 : toInteger(depth); - return depth < 1 ? copyArray(array) : baseFlatten(array, depth); + return baseFlatten(array, depth); } /** @@ -6233,7 +6233,7 @@ * // => [10, 20] */ var pullAt = rest(function(array, indexes) { - indexes = arrayMap(baseFlatten(indexes), String); + indexes = arrayMap(baseFlatten(indexes, 1), String); var result = baseAt(array, indexes); basePullAt(array, indexes.sort(compareAscending)); @@ -7184,7 +7184,7 @@ * // => ['a', 'c'] */ var wrapperAt = rest(function(paths) { - paths = baseFlatten(paths); + paths = baseFlatten(paths, 1); var length = paths.length, start = length ? paths[0] : 0, value = this.__wrapped__, @@ -7624,7 +7624,7 @@ * // => [1, 1, 2, 2] */ function flatMap(collection, iteratee) { - return baseFlatten(map(collection, iteratee)); + return baseFlatten(map(collection, iteratee), 1); } /** @@ -8246,7 +8246,7 @@ } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { iteratees.length = 1; } - return baseOrderBy(collection, baseFlatten(iteratees), []); + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); }); /*------------------------------------------------------------------------*/ @@ -8924,7 +8924,7 @@ * // => [100, 10] */ var overArgs = rest(function(func, transforms) { - transforms = arrayMap(baseFlatten(transforms), getIteratee()); + transforms = arrayMap(baseFlatten(transforms, 1), getIteratee()); var funcsLength = transforms.length; return rest(function(args) { @@ -9038,7 +9038,7 @@ * // => ['a', 'b', 'c'] */ var rearg = rest(function(func, indexes) { - return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); }); /** @@ -10808,7 +10808,7 @@ * // => ['a', 'c'] */ var at = rest(function(object, paths) { - return baseAt(object, baseFlatten(paths)); + return baseAt(object, baseFlatten(paths, 1)); }); /** @@ -11544,7 +11544,7 @@ if (object == null) { return {}; } - props = arrayMap(baseFlatten(props), String); + props = arrayMap(baseFlatten(props, 1), String); return basePick(object, baseDifference(keysIn(object), props)); }); @@ -11591,7 +11591,7 @@ * // => { 'a': 1, 'c': 3 } */ var pick = rest(function(object, props) { - return object == null ? {} : basePick(object, baseFlatten(props)); + return object == null ? {} : basePick(object, baseFlatten(props, 1)); }); /** @@ -13154,7 +13154,7 @@ * // => logs 'clicked docs' when clicked */ var bindAll = rest(function(object, methodNames) { - arrayEach(baseFlatten(methodNames), function(key) { + arrayEach(baseFlatten(methodNames, 1), function(key) { object[key] = bind(object[key], object); }); return object; From 784ee6a086742d606985f6e5259488b109cccc3e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Feb 2016 08:19:59 -0800 Subject: [PATCH 24/79] Remove fp `iterateeRearg` mapping. [closes #1971] --- fp/_baseConvert.js | 16 ++-------------- fp/_mapping.js | 7 ------- test/test-fp.js | 22 ---------------------- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index 3dd940401a..96cc185f47 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -109,13 +109,6 @@ function baseConvert(util, name, func, options) { }); }; - var iterateeRearg = function(func, indexes) { - return overArg(func, function(func) { - var n = indexes.length; - return baseArity(rearg(baseAry(func, n), indexes), n); - }); - }; - var overArg = function(func, iteratee, retArg) { return function() { var length = arguments.length; @@ -207,7 +200,6 @@ function baseConvert(util, name, func, options) { each(mapping.aryMethod[cap], function(otherName) { if (name == otherName) { var aryN = !isLib && mapping.iterateeAry[name], - reargIndexes = mapping.iterateeRearg[name], spreadStart = mapping.methodSpread[name]; result = wrapped; @@ -219,12 +211,8 @@ function baseConvert(util, name, func, options) { if (config.rearg && cap > 1 && (forceRearg || !mapping.skipRearg[name])) { result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]); } - if (config.cap) { - if (reargIndexes) { - result = iterateeRearg(result, reargIndexes); - } else if (aryN) { - result = iterateeAry(result, aryN); - } + if (config.cap && aryN) { + result = iterateeAry(result, aryN); } if (config.curry && cap > 1) { result = curry(result, cap); diff --git a/fp/_mapping.js b/fp/_mapping.js index 8975c1dd63..d3c65fbaa2 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -127,13 +127,6 @@ exports.iterateeAry = { 'transform': 2 }; -/** Used to map method names to iteratee rearg configs. */ -exports.iterateeRearg = { - 'findKey': [1], - 'findLastKey': [1], - 'mapKeys': [1] -}; - /** Used to map method names to rearg configs. */ exports.methodRearg = { 'assignInWith': [1, 2, 0], diff --git a/test/test-fp.js b/test/test-fp.js index c4345340e4..9662fcc656 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -458,28 +458,6 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('key methods'); - - (function() { - var object = { 'a': 1 }; - - QUnit.test('should provide the correct `iteratee` arguments', function(assert) { - assert.expect(3); - - _.each(['findKey', 'findLastKey', 'mapKeys'], function(methodName) { - var args; - - var actual = fp[methodName](function() { - args || (args = slice.call(arguments)); - }, object); - - assert.deepEqual(args, ['a'], 'fp.' + methodName); - }); - }); - }()); - - /*--------------------------------------------------------------------------*/ - QUnit.module('mutation methods'); (function() { From feafdb3c6ac0bf98006dd926207f79e1b0eccb99 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Wed, 10 Feb 2016 08:26:43 -0800 Subject: [PATCH 25/79] Fix jsdoc `type` tags. [closes #1976] [ci skip] --- lodash.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lodash.js b/lodash.js index 9e3882309c..de91964124 100644 --- a/lodash.js +++ b/lodash.js @@ -1509,7 +1509,7 @@ * * @static * @memberOf _ - * @type Object + * @type {Object} */ lodash.templateSettings = { @@ -1517,7 +1517,7 @@ * Used to detect `data` property values to be HTML-escaped. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'escape': reEscape, @@ -1525,7 +1525,7 @@ * Used to detect code to be evaluated. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'evaluate': reEvaluate, @@ -1533,7 +1533,7 @@ * Used to detect `data` property values to inject. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'interpolate': reInterpolate, @@ -1541,7 +1541,7 @@ * Used to reference the data object in the template text. * * @memberOf _.templateSettings - * @type string + * @type {string} */ 'variable': '', @@ -1549,7 +1549,7 @@ * Used to import variables into the compiled template. * * @memberOf _.templateSettings - * @type Object + * @type {Object} */ 'imports': { @@ -1557,7 +1557,7 @@ * A reference to the `lodash` function. * * @memberOf _.templateSettings.imports - * @type Function + * @type {Function} */ '_': lodash } @@ -2917,7 +2917,6 @@ * property of prototypes or treat sparse arrays as dense. * * @private - * @type Function * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ @@ -8257,7 +8256,7 @@ * * @static * @memberOf _ - * @type Function + * @type {Function} * @category Date * @returns {number} Returns the timestamp. * @example @@ -9459,7 +9458,7 @@ * * @static * @memberOf _ - * @type Function + * @type {Function} * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. @@ -9484,7 +9483,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. @@ -9507,7 +9505,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. @@ -9536,7 +9533,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. @@ -14511,7 +14507,7 @@ * * @static * @memberOf _ - * @type string + * @type {string} */ lodash.VERSION = VERSION; From 7efa921babc753e8b674e69a6357e34895d28c10 Mon Sep 17 00:00:00 2001 From: Artur Baybulatov Date: Wed, 10 Feb 2016 19:24:22 +0300 Subject: [PATCH 26/79] Add a note about browser usage of lodash-fp. [ci skip] --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 03591fa863..2dbf48bdd9 100644 --- a/README.md +++ b/README.md @@ -51,5 +51,6 @@ Create [custom builds](https://lodash.com/custom-builds) with only the features * [Release Notes](https://github.com/lodash/lodash/releases/tag/4.0.0) * [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences) * [Changelog](https://github.com/lodash/lodash/wiki/Changelog) + * [lodash-fp in-browser usage example] (https://github.com/lodash/lodash/wiki/lodash-fp-in-browser-usage-example) * [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap) * [More Resources](https://github.com/lodash/lodash/wiki/Resources) From d58d6f45cc76beb79ad80ab8a07a3ea4411d3cfe Mon Sep 17 00:00:00 2001 From: greenkeeperio-bot Date: Wed, 10 Feb 2016 11:34:00 -0800 Subject: [PATCH 27/79] Update glob to 7.0.0. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8de3747a66..54edacd9c9 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "dojo": "^1.10.4", "ecstatic": "^1.4.0", "fs-extra": "~0.26.5", - "glob": "^6.0.4", + "glob": "^7.0.0", "istanbul": "0.4.2", "jquery": "^2.2.0", "jscodeshift": "^0.3.13", From 1c47acd040d35d456754b2ca4f774679351bed42 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 00:16:43 -0800 Subject: [PATCH 28/79] Ensure `maxWait` isn't processed on a leading invocation if`leading` is `false` and there isn't an max delay queued. [closes #1964] --- lodash.js | 2 +- test/test.js | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lodash.js b/lodash.js index de91964124..673b88fc0b 100644 --- a/lodash.js +++ b/lodash.js @@ -8683,7 +8683,7 @@ lastCalled = stamp; } var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0 || remaining > maxWait; + isCalled = (remaining <= 0 || remaining > maxWait) && (leading || maxTimeoutId); if (isCalled) { if (maxTimeoutId) { diff --git a/test/test.js b/test/test.js index 70fae59217..82f54a48ce 100644 --- a/test/test.js +++ b/test/test.js @@ -3945,7 +3945,7 @@ }); QUnit.test('should cancel `maxDelayed` when `delayed` is invoked', function(assert) { - assert.expect(1); + assert.expect(2); var done = assert.async(); @@ -3958,9 +3958,14 @@ debounced(); setTimeout(function() { + debounced(); assert.strictEqual(callCount, 1); - done(); }, 128); + + setTimeout(function() { + assert.strictEqual(callCount, 2); + done(); + }, 192); }); QUnit.test('should invoke the `trailing` call with the correct arguments and `this` binding', function(assert) { @@ -20707,7 +20712,7 @@ }); }); - QUnit.test('should trigger a second throttled call as early as possible when invoked repeatedly', function(assert) { + QUnit.test('should trigger a second throttled call as soon as possible', function(assert) { assert.expect(2); var done = assert.async(); From 641112dd4dab2c47a8c9230c7d1df602705b1190 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 09:43:16 -0800 Subject: [PATCH 29/79] Attempt two to fix bizarro buffer test in Node v0.12. --- test/test.js | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/test/test.js b/test/test.js index 82f54a48ce..b513851118 100644 --- a/test/test.js +++ b/test/test.js @@ -463,6 +463,20 @@ return !(key == 'valueOf' && this && this.valueOf === 1) && _propertyIsEnumerable.call(this, key); }); + if (Buffer) { + defineProperty(root, 'Buffer', { + 'configurable': true, + 'enumerable': true, + 'get': function get() { + var caller = get.caller, + name = caller.name; + + if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) { + return Buffer; + } + } + }); + } if (Map) { setProperty(root, 'Map', (function() { var count = 0; @@ -470,31 +484,13 @@ if (count++) { return new Map; } - var result = {}; setProperty(root, 'Map', Map); - return result; + return {}; }; }())); setProperty(root.Map, 'toString', createToString('Map')); } - defineProperty(root, 'Buffer', (function() { - var count = 0, - version = lodashStable.get(process, 'versions.node'), - limit = /^0\.12\b/.test(version) ? 2 : 0; - - return { - 'configurable': true, - 'enumerable': true, - 'get': function() { - if (++count <= limit) { - return Buffer; - } - setProperty(root, 'Buffer', undefined); - } - }; - }())); - setProperty(root, 'Set', noop); setProperty(root, 'Symbol', undefined); setProperty(root, 'WeakMap', noop); From 8c5b64c7d7a04b05bab86bd5e8721783b57df9e9 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 12:58:38 -0800 Subject: [PATCH 30/79] Have browser fp convert auto wrap lodash if found. --- fp/_convertBrowser.js | 3 +++ test/test-fp.js | 16 ++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/fp/_convertBrowser.js b/fp/_convertBrowser.js index fd74897816..fbd217485b 100644 --- a/fp/_convertBrowser.js +++ b/fp/_convertBrowser.js @@ -11,4 +11,7 @@ function browserConvert(lodash, options) { return baseConvert(lodash, lodash, options); } +if (typeof _ == 'function') { + _ = browserConvert(_.runInContext()); +} module.exports = browserConvert; diff --git a/test/test-fp.js b/test/test-fp.js index 9662fcc656..1433713c25 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -35,10 +35,11 @@ )); /** Load stable Lodash and QUnit Extras. */ - var _ = root._ || load('../lodash.js'); - if (_) { - _ = _.runInContext(root); - } + var _ = root._ || (root._ = ( + _ = load('../lodash.js'), + _.runInContext(root) + )); + var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js'); if (QUnitExtras) { QUnitExtras.runInContext(root); @@ -63,8 +64,11 @@ }; }()); - var mapping = root.mapping || load('../fp/_mapping.js'), - fp = convert(_.runInContext()); + var fp = root.fp + ? (fp = _.noConflict(), _ = root._, fp) + : convert(_.runInContext()); + + var mapping = root.mapping || load('../fp/_mapping.js'); /*--------------------------------------------------------------------------*/ From b7ae5f088573da15354ead52dddd4383f96daaaa Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Thu, 11 Feb 2016 23:26:17 +0100 Subject: [PATCH 31/79] Add paragraph about making feature requests in docs [ci skip] --- CONTRIBUTING.md | 55 +++++++++++++++++++++++++++++++++++-------------- README.md | 6 ++++-- 2 files changed, 43 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7277cca3b6..cd2b148770 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,41 +1,64 @@ -# Contributing to lodash +# Contributing to Lodash -Contributions are always welcome. Before contributing, please read the [code of conduct](https://github.com/lodash/lodash/blob/master/CODE_OF_CONDUCT.md) & [search the issue tracker](https://github.com/lodash/lodash/issues); -your issue may have already been discussed or fixed in `master`. To contribute, [fork](https://help.github.com/articles/fork-a-repo/) lodash, commit your changes, & [send a pull request](https://help.github.com/articles/using-pull-requests/). +Contributions are always welcome. Before contributing, please read the +[code of conduct](https://github.com/lodash/lodash/blob/master/CODE_OF_CONDUCT.md) +& [search the issue tracker](https://github.com/lodash/lodash/issues); your issue +may have already been discussed or fixed in `master`. To contribute, +[fork](https://help.github.com/articles/fork-a-repo/) Lodash, commit your changes, +& [send a pull request](https://help.github.com/articles/using-pull-requests/). + +## Feature Requests + +Feature requests are always welcome. They should be submitted in the +[issue tracker](https://github.com/lodash/lodash/issues), with a description of +the expected behavior & use case, where they’ll remain closed until sufficient +interest has been shown by the community. Before submitting a request, +please search for similar ones in the +[closed issues](https://github.com/lodash/lodash/issues?q=is%3Aissue+is%3Aclosed). ## Pull Requests -For additions or bug fixes you should only need to modify `lodash.js`. -Include updated unit tests in the `test` directory as part of your pull request. -Don’t worry about regenerating the `dist/` or `doc/` files. +For additions or bug fixes you should only need to modify `lodash.js`. Include +updated unit tests in the `test` directory as part of your pull request. Don’t +worry about regenerating the `dist/` or `doc/` files. -Before running the unit tests you’ll need to install, `npm i`, [development dependencies](https://docs.npmjs.com/files/package.json#devdependencies). -Run unit tests from the command-line via `npm test`, or open `test/index.html` & `test/fp.html` in a web browser. -The [Backbone](http://backbonejs.org/) & [Underscore](http://underscorejs.org/) test suites are included as well. +Before running the unit tests you’ll need to install, `npm i`, +[development dependencies](https://docs.npmjs.com/files/package.json#devdependencies). +Run unit tests from the command-line via `npm test`, or open `test/index.html` & +`test/fp.html` in a web browser. The [Backbone](http://backbonejs.org/) & +[Underscore](http://underscorejs.org/) test suites are included as well. ## Contributor License Agreement -lodash is a member of the [Dojo Foundation](http://dojofoundation.org/). -As such, we request that all contributors sign the Dojo Foundation [contributor license agreement](http://dojofoundation.org/about/claForm). +Lodash is a member of the [Dojo Foundation](http://dojofoundation.org/). +As such, we request that all contributors sign the Dojo Foundation +[contributor license agreement (CLA)](http://dojofoundation.org/about/claForm). -For more information about CLAs, please check out Alex Russell’s excellent post, [“Why Do I Need to Sign This?”](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/). +For more information about CLAs, please check out Alex Russell’s excellent post, +[“Why Do I Need to Sign This?”](http://infrequently.org/2008/06/why-do-i-need-to-sign-this/). ## Coding Guidelines -In addition to the following guidelines, please follow the conventions already established in the code. +In addition to the following guidelines, please follow the conventions already +established in the code. - **Spacing**:
Use two spaces for indentation. No tabs. - **Naming**:
Keep variable & method names concise & descriptive.
- Variable names `index`, `collection`, & `callback` are preferable to `i`, `arr`, & `fn`. + Variable names `index`, `collection`, & `callback` are preferable to + `i`, `arr`, & `fn`. - **Quotes**:
- Single-quoted strings are preferred to double-quoted strings; however, please use a double-quoted string if the value contains a single-quote character to avoid unnecessary escaping. + Single-quoted strings are preferred to double-quoted strings; however, + please use a double-quoted string if the value contains a single-quote + character to avoid unnecessary escaping. - **Comments**:
- Please use single-line comments to annotate significant additions, & [JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for functions. + Please use single-line comments to annotate significant additions, & + [JSDoc-style](http://www.2ality.com/2011/08/jsdoc-intro.html) comments for + functions. Guidelines are enforced using [JSCS](https://www.npmjs.com/package/jscs): diff --git a/README.md b/README.md index 2dbf48bdd9..ef02bc796f 100644 --- a/README.md +++ b/README.md @@ -42,15 +42,17 @@ Lodash is available in a variety of other builds & module formats. * [lodash](https://www.npmjs.com/package/lodash) & [per method packages](https://www.npmjs.com/browse/keyword/lodash-modularized) * [lodash-amd](https://www.npmjs.com/package/lodash-amd) * [lodash-es](https://www.npmjs.com/package/lodash-es) & [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash) + * [lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide) CDN copies are available on [cdnjs](https://cdnjs.com/) & [jsDelivr](http://www.jsdelivr.com/).
Create [custom builds](https://lodash.com/custom-builds) with only the features you need. ## Further Reading - * [Release Notes](https://github.com/lodash/lodash/releases/tag/4.0.0) * [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences) * [Changelog](https://github.com/lodash/lodash/wiki/Changelog) - * [lodash-fp in-browser usage example] (https://github.com/lodash/lodash/wiki/lodash-fp-in-browser-usage-example) + * [Contributing & Feature Requests](https://github.com/lodash/lodash/blob/master/CONTRIBUTING.md) + * [FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) + * [Release Notes](https://github.com/lodash/lodash/releases/tag/4.0.0) * [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap) * [More Resources](https://github.com/lodash/lodash/wiki/Resources) From bd2428dde51ee38d0be1936f3dd6e30ef8dea219 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 21:02:44 -0800 Subject: [PATCH 32/79] Remove fp doc to be simplified in a later commit. --- lib/doc/apply-fp-mapping/common.js | 72 --- lib/doc/apply-fp-mapping/description.js | 39 -- lib/doc/apply-fp-mapping/example.js | 268 ----------- lib/doc/apply-fp-mapping/index.js | 13 - lib/doc/apply-fp-mapping/parameters.js | 206 --------- lib/fp/build-doc.js | 9 + lib/{doc/build.js => main/build-doc.js} | 18 +- package.json | 9 +- test/test-fp-doc.js | 580 ------------------------ 9 files changed, 16 insertions(+), 1198 deletions(-) delete mode 100644 lib/doc/apply-fp-mapping/common.js delete mode 100644 lib/doc/apply-fp-mapping/description.js delete mode 100644 lib/doc/apply-fp-mapping/example.js delete mode 100644 lib/doc/apply-fp-mapping/index.js delete mode 100644 lib/doc/apply-fp-mapping/parameters.js create mode 100644 lib/fp/build-doc.js rename lib/{doc/build.js => main/build-doc.js} (72%) delete mode 100644 test/test-fp-doc.js diff --git a/lib/doc/apply-fp-mapping/common.js b/lib/doc/apply-fp-mapping/common.js deleted file mode 100644 index ed510aa502..0000000000 --- a/lib/doc/apply-fp-mapping/common.js +++ /dev/null @@ -1,72 +0,0 @@ -var _ = require('lodash'), - Entry = require('docdown/lib/entry'); - -var baseGetParams = Entry.prototype.getParams; - -// Function copied from docdown/lib/entry that is not exported. -function getMultilineValue(string, tagName) { - var prelude = tagName == 'description' ? '^ */\\*\\*(?: *\\n *\\* *)?' : ('^ *\\*[\\t ]*@' + _.escapeRegExp(tagName) + '\\b'), - postlude = '(?=\\*\\s+\\@[a-z]|\\*/)', - result = _.result(RegExp(prelude + '([\\s\\S]*?)' + postlude, 'gm').exec(string), 1, ''); - - return _.trim(result.replace(RegExp('(?:^|\\n)[\\t ]*\\*[\\t ]' + (tagName == 'example' ? '?' : '*'), 'g'), '\n')); - -} - -// Function copied from docdown/lib/entry that is not exported. -function hasTag(string, tagName) { - tagName = tagName == '*' ? '\\w+' : _.escapeRegExp(tagName); - return RegExp('^ *\\*[\\t ]*@' + tagName + '\\b', 'm').test(string); -} - -/** - * Return the new ary of a given function. - * - * @param {object} mapping Mapping object that defines the arity of all functions. - * @param {String} name Name of the function associated to the call/function definition. - * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. - * @return {number} Ary of the function as an integer - */ -function getMethodAry(mapping, name, wrapped) { - var ary = _.find(mapping.caps, function(cap) { - return _.includes(mapping.aryMethod[cap], name) && cap; - }); - if (_.isNumber(ary) && wrapped) { - return ary - 1; - } - return ary; -} - -/** - * Reorder `params` for a given function definition/call. - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {*[]} params Parameters/arguments to reorder. - * @param {boolean} wrapped Flag indicating whether method is wrapped. Will decrement ary if true. - * @returns {*[]} Reordered parameters/arguments. - */ -function reorderParams(mapping, name, params, wrapped) { - // Check if reordering is needed. - if (!mapping || mapping.skipRearg[name]) { - return params; - } - var reargOrder = mapping.methodRearg[name] || mapping.aryRearg[getMethodAry(mapping, name, wrapped)]; - if (!reargOrder) { - return params; - } - // Reorder params. - var newParams = []; - reargOrder.forEach(function(newPosition, index) { - newParams[newPosition] = params[index]; - }); - return newParams; -} - -module.exports = { - baseGetParams: baseGetParams, - getMultilineValue: getMultilineValue, - hasTag: hasTag, - getMethodAry: getMethodAry, - reorderParams: reorderParams -}; diff --git a/lib/doc/apply-fp-mapping/description.js b/lib/doc/apply-fp-mapping/description.js deleted file mode 100644 index f6b4f1bdd4..0000000000 --- a/lib/doc/apply-fp-mapping/description.js +++ /dev/null @@ -1,39 +0,0 @@ -var _ = require('lodash'), - j = require('jscodeshift'), - Entry = require('docdown/lib/entry'), - common = require('./common'); - -var baseGetDesc = Entry.prototype.getDesc; - -var lineBreaksRegex = /\n?$/g; - -/** - * Return the `description` of the entry, only without the possible note about mutation. - * - * @returns {Function} Updated description. - */ -function getReorderedExample() { - var lines = baseGetDesc.call(this).split('\n'); - - var indexOfLine = _.findIndex(lines, function(line) { - return _.includes(line, 'mutate'); - }); - - if (indexOfLine === -1) { - return lines.join('\n'); - } - - var linesToDelete = 1; - while (indexOfLine + linesToDelete < lines.length && - !lines[indexOfLine + linesToDelete].startsWith(' 1) { - // defaultValue is probably of the type 'someArg.length' - // Other more complicated cases could be handled but none exist as of this writing. - return memberExpressiontoASTNode(j, args[indexOfReferencedParam], splitDefaultValue[1]); - } - return args[indexOfReferencedParam]; - } - return stringToASTNode(j, defaultValue); -} - -/** - * Same as _.map, but applied in reverse order. - * - * @param {Array} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @return {Array} Returns the new mapped array. - */ -function mapRight(array, iteratee) { - var res = []; - var index = array.length; - while (index--) { - res = [iteratee(array[index], index)].concat(res); - } - return res; -} - -/** - * Return the list of arguments, augmented by the default value of the arguments that were ommitted. - * The augmentation only happens when the method call is made without some of the optional arguments, - * and when the arguments these optional arguments have become compulsory. - * For a `function fn(a, b, c=0, d=b.length) { ... }` with an arity of 4, - * when called with `args` [a, ['b']], returns [a, ['b'], 0, ['b'].length]. - * If possible, the value will be evaluated such that ̀`['b'].length` becomes `1`. - * - * @param {object} j JSCodeShift object. - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {ASTObject[]} args Arguments to concatenate. - * @param {string[][]} paramsDescription Description of the expected params. - * @return {ASTObject[]} Args along with missing arguments. - */ -function addMissingArguments(j, mapping, name, args, paramsDescription) { - var ary = common.getMethodAry(mapping, name); - - if (ary === undefined) { - console.log('WARNING: method `' + name + '` is not capped'); - } - - ary = ary || 1; - if (ary <= args.length) { - return args; - } - var paramNames = paramsDescription.map(paramName); - var tmpArgs = _.clone(args); - var newArgs = mapRight(_.take(paramsDescription, ary), function(paramDescription, index) { - if (index === tmpArgs.length - 1) { - return tmpArgs.pop(); - } - var defaultValue = getDefaultValue(paramDescription); - if (defaultValue !== null) { - return defaultValueToASTNode(j, defaultValue, args, paramNames); - } - return tmpArgs.pop(); - }); - return newArgs; -} - -/** - * Concatenate arguments into an array of arguments. - * For a `function fn(a, b, ...args) { ... }` with an arity of 3, - * when called with `args` [a, b, c, d, e, f], returns [a, b, [c, d, e, f]]. - * - * @param {object} j JSCodeShift object. - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {String} name Name of the function associated to the call/function definition. - * @param {ASTObject[]} args Arguments to concatenate. - * @return {ASTObject[]} Concatenated arguments - */ -function concatExtraArgs(j, mapping, name, args) { - var ary = common.getMethodAry(mapping, name); - if (args.length <= ary) { - return args; - } - - var concatenatedArgs = j.arrayExpression(_.takeRight(args, args.length - ary + 1)); - return _.take(args, ary - 1).concat(concatenatedArgs); -} - -/** - * Reorder the args in the example if needed, and eventually merges them when - * the method is called with more args than the method's ary. - * - * @param {object} j JSCodeShift object. - * @param {ASTObject} root AST representation of the example - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @return {ASTObject} AST object where the arguments are reordered/merged - */ -function reorderMethodArgs(j, root, mapping, paramsDescription) { - root.find(j.CallExpression, { callee: { object: {name: '_' }}}) - .replaceWith(function(callExpr, i) { - var value = callExpr.value; - var name = value.callee.property.name; - var argsIncludingMissingOnes = addMissingArguments(j, mapping, name, value.arguments, paramsDescription); - var args = concatExtraArgs(j, mapping, name, argsIncludingMissingOnes); - return j.callExpression( - value.callee, - common.reorderParams(mapping, name, args) - ); - }); -} - -/** - * Remove calls to `console.log` from `codeSample`. - * - * @param {string} codeSample string to remove the calls from. - * @return {string} Updated code sample. - */ -function removeConsoleLogs(codeSample) { - return codeSample - .split('\n') - .filter(function(line) { - return !line.startsWith('console.log'); - }) - .join('\n'); -} - -/** - * Updates a code sample so that the arguments in the call are reordered according to `mapping`. - * - * @param {object} mapping Mapping object that defines if and how the arguments will be reordered. - * @param {string} codeSample Code sample to update. - * @returns {string} Updated code sample. - */ -function reorderParamsInExample(mapping, codeSample, paramsDescription) { - var root = j(removeConsoleLogs(codeSample)); - try { - reorderMethodArgs(j, root, mapping, paramsDescription); - } catch (error) { - console.error(codeSample); - console.error(error.stack); - process.exit(1); - } - return root.toSource(); -} - -/** - * Returns the original, not reordered, list of parameters. - * - * @param {Entry} entryItem Entry whose parameters to get. - * @return {string[][]} List of args. - */ -function getOriginalParams(entryItem) { - var prev = entryItem._params; - entryItem._params = undefined; - common.baseGetParams.call(entryItem); - var result = entryItem._params; - entryItem._params = prev; - return result; -} - -/** - * Returns a function that extracts the entry's `example` data, - * where function call arguments are reordered according to `mapping`. - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @returns {Function} Function that returns the entry's `example` data. - */ -function getReorderedExample(mapping) { - return function() { - var result = common.getMultilineValue(this.entry, 'example'); - if (!result) { - return result; - } - - var paramsDescription = getOriginalParams(this); - var resultReordered = reorderParamsInExample(mapping, result, paramsDescription); - return '```' + this.lang + '\n' + resultReordered + '\n```'; - }; -} - -module.exports = getReorderedExample; diff --git a/lib/doc/apply-fp-mapping/index.js b/lib/doc/apply-fp-mapping/index.js deleted file mode 100644 index 5ffa02124e..0000000000 --- a/lib/doc/apply-fp-mapping/index.js +++ /dev/null @@ -1,13 +0,0 @@ -var Entry = require('docdown/lib/entry'), - getUpdatedDesc = require('./description'), - getReorderedParams = require('./parameters'), - getReorderedExample = require('./example'); - -/** - * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`. - */ -module.exports = function applyFPMapping(mapping) { - Entry.prototype.getDesc = getUpdatedDesc; - Entry.prototype.getParams = getReorderedParams(mapping); - Entry.prototype.getExample = getReorderedExample(mapping); -}; diff --git a/lib/doc/apply-fp-mapping/parameters.js b/lib/doc/apply-fp-mapping/parameters.js deleted file mode 100644 index 3b0713aa28..0000000000 --- a/lib/doc/apply-fp-mapping/parameters.js +++ /dev/null @@ -1,206 +0,0 @@ -var _ = require('lodash'), - j = require('jscodeshift'), - Entry = require('docdown/lib/entry'), - common = require('./common'); - -var baseGetParams = Entry.prototype.getParams; - -var dotsRegex = /^\.\.\./; -var parensRegex = /^\((.*)\)$/; -var squareBracketsRegex = /^\[(.*)\]$/; -var arrayRegex = /\[\]$/; - -/** - * Return whether method is wrapped. - * - * @param {Entry} entry Entry to look at. - * @return {Boolean} true if the method is wrapped, false if it is static. - */ -function isWrapped(entry) { - return !common.hasTag(entry, 'static'); -} - -/** - * Extract the entry's `name` data. - * Sub-part of Entry.prototype.getCall() that fetches the name. Using `Entry.prototype.getCall()` - * makes a call to getParams(), which itself call getBaseName --> infinite recursion. - * - * @param {object} entry Entry whose name to extract. - * @returns {string} The entry's `name` data. - */ -function getBaseName(entry) { - var result = /\*\/\s*(?:function\s+([^(]*)|(.*?)(?=[:=,]))/.exec(entry); - if (result) { - result = (result[1] || result[2]).split('.').pop(); - result = _.trim(_.trim(result), "'").split('var ').pop(); - result = _.trim(result); - } - // Get the function name. - return _.result(/\*[\t ]*@name\s+(.+)/.exec(entry), 1, result || ''); -} - -/** - * Return `types` as '(X|Y|...)' if `types` contains multiple values, `types[0]` otherwise. - * - * @param {string[]} types Possible types of the parameter. - * @return {string} `types` as a string. - */ -function wrapInParensIfMultiple(types) { - if (types.length > 1) { - return '(' + types.join('|') + ')'; - } - return types[0]; -} - -/** - * Transform parameter type from 'X' to 'X|X[]'. - * - * @param {string[]} param Array whose first item is a description of the parameter type. - * @return {string[]} `param` with the updated type. - */ -function singleItemOrArrayOf(type) { - return type + '|' + type + '[]'; -} - -/** - * Replace parameter type from something like `...number` to `number|number[]`. - * - * @param {string[]} param Array whose first item is a description of the parameter type. - * @return {string[]} `param` with the updated type. - */ -function removeDotsFromTypeAndAllowMultiple(param) { - var type = param[0]; - if (!dotsRegex.test(type)) { - return param; - } - - var newType = _.chain(type) - .replace(dotsRegex, '') - .replace(parensRegex, '$1') - .split('|') - .map(function(s) { - return s.replace(arrayRegex, ''); - }) - .uniq() - .thru(wrapInParensIfMultiple) - .thru(singleItemOrArrayOf) - .value(); - - return [newType].concat(_.tail(param)); -} - -/** - * Replace parameter type from something like `...number` to `number|number[]`. - * - * @param {string[]} param Array whose first item is a description of the parameter type. - * @return {string[]} `param` with the updated type. - */ -function removeDotsFromType(param) { - var type = param[0]; - if (!dotsRegex.test(type)) { - return param; - } - - var newType = type - .replace(dotsRegex, '') - .replace(parensRegex, '$1'); - - return [newType].concat(_.tail(param)); -} - -/** - * Find and duplicate the parameter with a type of the form '...x'. - * - * @param {string} name Name of the method. - * @param {string[]} params Description of the parameters of the method. - * @return {string[]} Updated parameters. - */ -function duplicateRestArrays(name, params) { - var indexOfRestParam = _.findIndex(params, function(param) { - return dotsRegex.test(param[0]); - }); - if (indexOfRestParam === -1) { - console.log('WARNING: method `' + name + '`', - 'is capped to more arguments than its declared number of parameters,', - 'but does not have a parameter like `...x`'); - } - // duplicates param[indexOfRestParam] at its position - return params.slice(0, indexOfRestParam + 1) - .concat(params.slice(indexOfRestParam)); -} - -/** - * Remove the optional default value and brackets around the name of the method. - * - * @param {string[]} param Array whose second item is the name of the param of the form - * 'name', '[name]' or [name=defaultValue]. - * @return {string[]} `param` with the updated name. - */ -function removeDefaultValue(param) { - var name = param[1] - .replace(squareBracketsRegex, '$1') - .split('=') - [0]; - - return [param[0], name, param[2]]; -} - -/** - * Return the updated list of parameters of a method described by `entry`, - * according to changes described by `mapping`. Will, if needed: - * - reorder the arguments - * - remove default values and brackets around previously optional arguments - * - remove ignored arguments - * - duplicate rest arguments if the number of params is less than its cap - * - de-restify arguments - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @param {Entry} entry Method to update. - * @param {string[][]} params List of the original parameters of the method. - * @return {string[][]} Updated list of params. - */ -function updateParamsDescription(mapping, entry, params) { - var tmpParams; - var name = getBaseName(entry); - var ary = common.getMethodAry(mapping, name); - - var wrapped = isWrapped(entry); - if (wrapped) { - // Needs one less argument when wrapped - ary = ary - 1; - params.shift(); - } - - if (ary > params.length) { - tmpParams = duplicateRestArrays(name, params) - .map(removeDotsFromType); - } else { - tmpParams = params - .map(removeDotsFromTypeAndAllowMultiple); - } - tmpParams = _.take(tmpParams, ary).map(removeDefaultValue); - return common.reorderParams(mapping, name, tmpParams, wrapped); -} - -/** - * Return a function that extracts the entry's `param` data, reordered according to `mapping`. - * - * @param {object} mapping Mapping object that defines if and how the `params` will be reordered. - * @returns {Function} Function that returns the entry's `param` data. - */ -function getReorderedParams(mapping) { - return function(index) { - if (!this._params) { - // Call baseGetParams in order to compute `this._params`. - baseGetParams.call(this); - // Reorder params according to the `mapping`. - this._params = updateParamsDescription(mapping, this.entry, this._params); - } - return baseGetParams.call(this, index); - }; -} - -/** - * Updates `docdown` `Entry`'s prototype so that parameters/arguments are reordered according to `mapping`. - */ -module.exports = getReorderedParams; diff --git a/lib/fp/build-doc.js b/lib/fp/build-doc.js new file mode 100644 index 0000000000..0e9bd604a0 --- /dev/null +++ b/lib/fp/build-doc.js @@ -0,0 +1,9 @@ +'use strict'; + +/*----------------------------------------------------------------------------*/ + +function build(type) { + +} + +build(_.last(process.argv)); diff --git a/lib/doc/build.js b/lib/main/build-doc.js similarity index 72% rename from lib/doc/build.js rename to lib/main/build-doc.js index 1ca1e9611f..e4057260ef 100644 --- a/lib/doc/build.js +++ b/lib/main/build-doc.js @@ -5,13 +5,9 @@ var _ = require('lodash'), fs = require('fs-extra'), path = require('path'); -var mapping = require('../../fp/_mapping'), - applyFPMapping = require('./apply-fp-mapping'); - var basePath = path.join(__dirname, '..', '..'), docPath = path.join(basePath, 'doc'), - readmePath = path.join(docPath, 'README.md'), - fpReadmePath = path.join(docPath, 'fp.md'); + readmePath = path.join(docPath, 'README.md'); var pkg = require('../../package.json'), version = pkg.version; @@ -49,15 +45,11 @@ function onComplete(error) { } } -function build(fpFlag, type) { - if (fpFlag) { - applyFPMapping(mapping); - } +function build(type) { var options = _.defaults({}, config.base, config[type]), - markdown = docdown(options), - filePath = fpFlag ? fpReadmePath : readmePath; + markdown = docdown(options); - fs.writeFile(filePath, postprocess(markdown), onComplete); + fs.writeFile(readmePath, postprocess(markdown), onComplete); } -build(_.includes(process.argv, '--fp'), _.last(process.argv)); +build(_.last(process.argv)); diff --git a/package.json b/package.json index 54edacd9c9..3635e3394c 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,11 @@ "glob": "^7.0.0", "istanbul": "0.4.2", "jquery": "^2.2.0", - "jscodeshift": "^0.3.13", "jscs": "^2.9.0", "lodash": "^3.10.1", "platform": "^1.3.1", "qunit-extras": "^1.4.5", "qunitjs": "~1.21.0", - "recast": "^0.11.0", "request": "^2.69.0", "requirejs": "^2.1.22", "sauce-tunnel": "^2.4.0", @@ -36,10 +34,8 @@ "build:fp-modules": "node lib/fp/build-modules.js", "build:main": "node lib/main/build-dist.js", "build:main-modules": "node lib/main/build-modules.js", - "doc": "node lib/doc/build github", - "doc:fp": "node lib/doc/build --fp github", - "doc:fp:site": "node lib/doc/build --fp site", - "doc:site": "node lib/doc/build site", + "doc": "node lib/main/build-doc github", + "doc:site": "node lib/main/build-doc site", "prepublish": "npm run style", "pretest": "npm run build", "style": "npm run style:main & npm run style:fp & npm run style:perf & npm run style:test", @@ -48,7 +44,6 @@ "style:perf": "jscs perf/*.js perf/**/*.js", "style:test": "jscs test/*.js test/**/*.js", "test": "npm run test:main && npm run test:fp && npm run test:docs", - "test:docs": "node test/test-fp-doc", "test:fp": "node test/test-fp", "test:main": "node test/test" } diff --git a/test/test-fp-doc.js b/test/test-fp-doc.js deleted file mode 100644 index 7900d703e4..0000000000 --- a/test/test-fp-doc.js +++ /dev/null @@ -1,580 +0,0 @@ -;(function() { - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as a reference to the global object. */ - var root = (typeof global == 'object' && global) || this; - - var phantom = root.phantom, - amd = root.define && define.amd, - document = !phantom && root.document, - noop = function() {}, - argv = root.process && process.argv; - - /** Use a single "load" function. */ - var load = (!amd && typeof require == 'function') - ? require - : noop; - - /** The unit testing framework. */ - var QUnit = root.QUnit || (root.QUnit = ( - QUnit = load('../node_modules/qunitjs/qunit/qunit.js') || root.QUnit, - QUnit = QUnit.QUnit || QUnit - )); - - /** Load stable Lodash and QUnit Extras. */ - var _ = root._ || load('../lodash.js'); - if (_) { - _ = _.runInContext(root); - } - var QUnitExtras = load('../node_modules/qunit-extras/qunit-extras.js'); - if (QUnitExtras) { - QUnitExtras.runInContext(root); - } - - var mapping = root.mapping || load('../fp/_mapping.js'), - applyFPMapping = load('../lib/doc/apply-fp-mapping'), - Entry = load('docdown/lib/entry'); - - /*--------------------------------------------------------------------------*/ - - function toCommentLine(line) { - return ' * ' + line; - } - - function toEntry(name, paramLines, exampleLines, attachedToPrototype) { - var start = [ - '/**', - ' * ', - ' * Foo', - ' * ' - ]; - var end = [ - ' */', - 'function ' + name + '(a, b, c) {', - '', - '}' - ]; - var staticLine = attachedToPrototype ? [] : [' * @static']; - var params = paramLines.map(function(line) { - return ' * @param ' + line; - }); - var example = (exampleLines || []).map(toCommentLine); - - return [].concat(start, staticLine, params, [' * @example'], example, end).join('\n'); - } - - var differenceBySource = toEntry('differenceBy', [ - '{Array} array The array to inspect.', - '{...Array} [values] The values to exclude.', - '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' - ], [ - '_.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor);', - '// → [3.1, 1.3]', - '', - '// The `_.property` iteratee shorthand.', - "_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');", - "// → [{ 'x': 2 }]" - ]); - - var setParams = [ - '{Object} object The object to modify.', - '{Array|string} path The path of the property to set.', - '{*} value The value to set.' - ]; - - /*--------------------------------------------------------------------------*/ - - if (argv) { - console.log('Running doc generation tests.'); - } - - mapping.aryMethod[2].push('customFun'); - applyFPMapping(mapping); - - /*--------------------------------------------------------------------------*/ - - QUnit.module('getExample'); - - (function() { - QUnit.test('should reorder parameters', function(assert) { - assert.expect(1); - - var entry = new Entry(differenceBySource, differenceBySource); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - '_.differenceBy(Math.floor, [4.4, 2.5], [3.1, 2.2, 1.3]);', - '// → [3.1, 1.3]', - '', - '// The `_.property` iteratee shorthand.', - "_.differenceBy('x', [{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }]);", - "// → [{ 'x': 2 }]", - '```' - ].join('\n')); - }); - - QUnit.test('should reorder parameters that have a special order', function(assert) { - assert.expect(1); - - var example = toEntry('set', setParams, [ - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set(object, 'a[0].b.c', 4);", - "_.set(object, 'x[0].y.z', 5);", - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set('a[0].b.c', 4, object);", - "_.set('x[0].y.z', 5, object);", - '```' - ].join('\n')); - }); - - QUnit.test('should preserve comments', function(assert) { - assert.expect(1); - - var example = toEntry('set', setParams, [ - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set(object, 'a[0].b.c', 4);", - '// => 4', - "_.set(object, 'x[0].y.z', 5);", - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - "_.set('a[0].b.c', 4, object);", - '// => 4', - "_.set('x[0].y.z', 5, object);", - '```' - ].join('\n')); - }); - - QUnit.test('should remove console.logs from example', function(assert) { - assert.expect(1); - - var example = toEntry('set', setParams, [ - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - '', - "_.set(object, 'a[0].b.c', 4);", - 'console.log(object.a[0].b.c);', - '// => 4', - '', - "_.set(object, 'x[0].y.z', 5);", - 'console.log(object.x[0].y.z);', - '// => 5' - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - "var object = { 'a': [{ 'b': { 'c': 3 } }] };", - '', - "_.set('a[0].b.c', 4, object);", - '// => 4', - '', - "_.set('x[0].y.z', 5, object);", - '// => 5', - '```' - ].join('\n')); - }); - - QUnit.test('should merge extra arguments into an array', function(assert) { - assert.expect(1); - - var example = toEntry('pullAt', [ - '{Array} array The array to modify.', - '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + - ' * specified individually or in arrays.' - ], [ - 'var array = [5, 10, 15, 20];', - 'var evens = _.pullAt(array, 1, 3);', - '', - 'console.log(array);', - '// => [5, 15]', - '', - 'console.log(evens);', - '// => [10, 20]' - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - 'var array = [5, 10, 15, 20];', - 'var evens = _.pullAt([1, 3], array);', - '', - '// => [5, 15]', - '', - '// => [10, 20]', - '```' - ].join('\n')); - }); - - QUnit.test('should inject default values into optional arguments that became compulsory', function(assert) { - assert.expect(1); - - var example = toEntry('sampleSize', [ - '{Array|Object} collection The collection to sample.', - '{number} [n=0] The number of elements to sample.' - ], [ - '_.sampleSize([1, 2, 3]);', - '// => [3, 1]', - '', - '_.sampleSize([1, 2, 3], 4);', - '// => [2, 3, 1]' - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - '_.sampleSize(0, [1, 2, 3]);', - '// => [3, 1]', - '', - '_.sampleSize(4, [1, 2, 3]);', - '// => [2, 3, 1]', - '```' - ].join('\n')); - }); - - QUnit.test('should inject referenced values into optional arguments that became compulsory, ' + - - 'if a parameter\'s default value references parameter (direct reference)', - function(assert) { - assert.expect(1); - - var example = toEntry('customFun', [ - '{Array} array Array', - '{number} [foo=array] Foo' - ], [ - '_.customFun([1, 2, 3]);', - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - '_.customFun([1, 2, 3], [1, 2, 3]);', - '```' - ].join('\n')); - }); - - QUnit.test('should inject referenced values into optional arguments that became compulsory, ' + - 'if a parameter\'s default value references parameter (member expression)', - function(assert) { - assert.expect(1); - - var example = toEntry('fill', [ - '{Array} array The array to fill.', - '{*} value The value to fill `array` with.', - '{number} [start=0] The start position.', - '{number} [end=array.length] The end position.' - ], [ - 'var array = [1, 2, 3];', - '', - "_.fill(array, 'a');", - 'console.log(array);', - "// => ['a', 'a', 'a']", - '', - '_.fill(Array(3), 2, 1);', - '// => [undefined, 2, 2]', - '', - "_.fill([4, 6, 8, 10], '*');", - "// => [*, '*', '*', *]" - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - 'var array = [1, 2, 3];', - '', - "_.fill(0, array.length, 'a', array);", - "// => ['a', 'a', 'a']", - '', - '_.fill(1, 3, 2, Array(3));', - '// => [undefined, 2, 2]', - '', - "_.fill(0, 4, '*', [4, 6, 8, 10]);", - "// => [*, '*', '*', *]", - '```' - ].join('\n')); - }); - - QUnit.test('should inject default values in the middle of the arguments', function(assert) { - assert.expect(1); - - var example = toEntry('inRange', [ - '{number} number The number to check.', - '{number} [start=0] The start of the range.', - '{number} end The end of the range.' - ], [ - '_.inRange(4, 8);', - '// => true' - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - '_.inRange(8, 0, 4);', - '// => true', - '```' - ].join('\n')); - }); - - QUnit.test('should not use ignored params as default values', function(assert) { - assert.expect(1); - - var example = toEntry('drop', [ - '{Array} array The array to query.', - '{number} [n=1] The number of elements to drop.', - '{Object} [guard] Enables use as an iteratee for functions like `_.map`.' - ], [ - '_.drop([1, 2, 3]);', - '// => [2, 3]' - ]); - var entry = new Entry(example, example); - - var actual = entry.getExample(); - - assert.equal(actual, [ - '```js', - '_.drop(1, [1, 2, 3]);', - '// => [2, 3]', - '```' - ].join('\n')); - }); - }()); - - /*--------------------------------------------------------------------------*/ - - QUnit.module('getParams'); - - (function() { - QUnit.test('should reorder arguments and remove default values', function(assert) { - assert.expect(1); - - var example = toEntry('differenceBy', [ - '{Array} array The array to inspect.', - '{...Array} [values] The values to exclude.', - '{Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Function|Object|string', 'iteratee', 'The iteratee invoked per element. '], - ['Array|Array[]', 'values', 'The values to exclude. '], - ['Array', 'array', 'The array to inspect. '] - ]); - }); - - QUnit.test('should reorder arguments that have a special order', function(assert) { - assert.expect(1); - - var example = toEntry('set', [ - '{Object} object The object to modify.', - '{Array|string} path The path of the property to set.', - '{*} value The value to set.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Array|string', 'path', 'The path of the property to set. '], - ['*', 'value', 'The value to set. '], - ['Object', 'object', 'The object to modify. '], - ]); - }); - - QUnit.test('should transform rest arguments into an array', function(assert) { - assert.expect(1); - - var example = toEntry('pullAt', [ - '{Array} array The array to modify.', - '{...(number|number[])} [indexes] The indexes of elements to remove,\n' + - ' * specified individually or in arrays.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - // TODO Remove this line in favor of the commented one. - // Is linked to a docdown issue (https://github.com/jdalton/docdown/pull/37) - // that does not handle parens in the arguments well - ['((number|number)|((number|number)[]', 'indexes', 'The indexes of elements to remove, specified individually or in arrays. '], - // ['number|number[]', '[indexes]', 'The indexes of elements to remove, specified individually or in arrays. '], - ['Array', 'array', 'The array to modify. '], - ]); - }); - - QUnit.test('should duplicate and de-restify "rest" parameters if there are less parameters than cap', function(assert) { - assert.expect(1); - - var example = toEntry('intersectionWith', [ - '{...Array} [arrays] The arrays to inspect.', - '{Function} [comparator] The comparator invoked per element.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Function', 'comparator', 'The comparator invoked per element. '], - ['Array', 'arrays', 'The arrays to inspect. '], - ['Array', 'arrays', 'The arrays to inspect. '] - ]); - }); - - QUnit.test('should consider method to have an ary of `ary - 1` when capped and wrapped', function(assert) { - assert.expect(1); - - var wrapped = true; - var example = toEntry('flatMap', [ - '{Array} array The array to iterate over.', - '{Function|Object|string} [iteratee=_.identity] The function invoked per iteration.' - ], [], wrapped); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['Function|Object|string', 'iteratee', 'The function invoked per iteration. '] - ]); - }); - - QUnit.test('should remove arguments ignored because of capping (includes)', function(assert) { - assert.expect(1); - - var example = toEntry('includes', [ - '{Array|Object|string} collection The collection to search.', - '{*} value The value to search for.', - '{number} [fromIndex=0] The index to search from.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['*', 'value', 'The value to search for. '], - ['Array|Object|string', 'collection', 'The collection to search. '] - ]); - }); - - QUnit.test('should remove arguments ignored because of capping (trim)', function(assert) { - assert.expect(1); - - var example = toEntry('trim', [ - "{string} [string=''] The string to trim.", - '{string} [chars=whitespace] The characters to trim.' - ]); - var entry = new Entry(example, example); - - var actual = entry.getParams(); - - assert.deepEqual(actual, [ - ['string', 'string', 'The string to trim. '] - ]); - }); - }()); - - /*--------------------------------------------------------------------------*/ - - QUnit.module('getDesc'); - - (function() { - function toSourceWithDescription(name, description) { - var start = [ - '/**', - ' * ' - ]; - - var end = [ - ' * @static', - ' * ', - ' */', - 'function ' + name + '(a, b, c) {', - '', - '}' - ]; - - var descriptionLines = description.map(toCommentLine); - return [].concat(start, descriptionLines, end).join('\n'); - } - - QUnit.test('should remove notes about mutators arguments and remove default values', function(assert) { - assert.expect(1); - - var example = toSourceWithDescription('pullAt', [ - 'Removes elements from `array` corresponding to `indexes` and returns an', - 'array of removed elements.', - '', - '**Note:** Unlike `_.at`, this method mutates `array`.', - '' - ]); - - var entry = new Entry(example, example); - - var actual = entry.getDesc(); - - assert.equal(actual, [ - 'Removes elements from `array` corresponding to `indexes` and returns an', - 'array of removed elements.' - ].join('\n')); - }); - - QUnit.test('should remove following related lines', function(assert) { - assert.expect(1); - - var example = toSourceWithDescription('assign', [ - 'Assigns own enumerable properties of source objects to the destination', - 'object. Source objects are applied from left to right. Subsequent sources', - 'overwrite property assignments of previous sources.', - '', - '**Note:** This method mutates `object` and is loosely based on', - '[`Object.assign`](https://mdn.io/Object/assign).', - '' - ]); - - var entry = new Entry(example, example); - - var actual = entry.getDesc(); - - assert.equal(actual, [ - 'Assigns own enumerable properties of source objects to the destination', - 'object. Source objects are applied from left to right. Subsequent sources', - 'overwrite property assignments of previous sources.', - ].join('\n')); - }); - }()); - - QUnit.config.asyncRetries = 10; - QUnit.config.hidepassed = true; - - if (!document) { - QUnit.config.noglobals = true; - QUnit.load(); - } -}.call(this)); From 53b3f81abee94d9575474edd10e81191a36f658d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 22:56:33 -0800 Subject: [PATCH 33/79] Ensure `_.merge` deep clones array/typed-array/plain-object sources. [closes #1987] --- lodash.js | 6 +++--- test/test.js | 22 +++++++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lodash.js b/lodash.js index 673b88fc0b..5dafbfa1cf 100644 --- a/lodash.js +++ b/lodash.js @@ -3081,7 +3081,7 @@ } else { isCommon = false; - newValue = baseClone(srcValue); + newValue = baseClone(srcValue, true); } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { @@ -3090,10 +3090,10 @@ } else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { isCommon = false; - newValue = baseClone(srcValue); + newValue = baseClone(srcValue, true); } else { - newValue = srcIndex ? baseClone(objValue) : objValue; + newValue = objValue; } } else { diff --git a/test/test.js b/test/test.js index b513851118..b340daa94c 100644 --- a/test/test.js +++ b/test/test.js @@ -13937,15 +13937,27 @@ assert.deepEqual(actual.a, [[3, 4, 3]]); }); - QUnit.test('should shallow clone array/typed-array/plain-object sources', function(assert) { + QUnit.test('should deep clone array/typed-array/plain-object sources', function(assert) { assert.expect(1); - var values = [[], new (Uint8Array || Object), {}], + var typedArray = Uint8Array + ? new Uint8Array(new ArrayBuffer(2)) + : { 'buffer': [0, 0] }; + + var props = ['0', 'a', 'buffer'], + values = [[{ 'a': 1 }], { 'a': [1] }, typedArray], expected = lodashStable.map(values, alwaysTrue); - var actual = lodashStable.map(values, function(value) { - var object = _.merge({}, { 'value': value }); - return object.value !== value && lodashStable.isEqual(object.value, value); + var actual = lodashStable.map(values, function(value, index) { + var key = props[index], + object = _.merge({}, { 'value': value }), + newValue = object.value; + + return ( + newValue !== value && + newValue[key] !== value[key] && + lodashStable.isEqual(newValue, value) + ); }); assert.deepEqual(actual, expected); From b1ed66c6f58995b6ec01d26de368cdac97d4664a Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 22:57:25 -0800 Subject: [PATCH 34/79] Add another `fp.inRange` test. --- test/test-fp.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test-fp.js b/test/test-fp.js index 1433713c25..397cdfbfe2 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -861,9 +861,10 @@ (function() { QUnit.test('should have an argument order of `start`, `end`, then `value`', function(assert) { - assert.expect(1); + assert.expect(2); assert.strictEqual(fp.inRange(2)(4)(3), true); + assert.strictEqual(fp.inRange(-2)(-6)(-3), true); }); }()); From a3676618af52a608ba60ebcae316ae32ffc4d7ef Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 23:01:38 -0800 Subject: [PATCH 35/79] Reorg templates. --- lib/fp/build-modules.js | 2 +- lib/fp/template/doc/wiki.jst | 1 + lib/fp/template/{ => modules}/_util.jst | 0 lib/fp/template/{ => modules}/alias.jst | 0 lib/fp/template/{ => modules}/category.jst | 0 lib/fp/template/{ => modules}/convert.jst | 0 lib/fp/template/{ => modules}/fp.jst | 0 lib/fp/template/{ => modules}/module.jst | 0 lib/fp/template/{ => modules}/thru.jst | 0 9 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 lib/fp/template/doc/wiki.jst rename lib/fp/template/{ => modules}/_util.jst (100%) rename lib/fp/template/{ => modules}/alias.jst (100%) rename lib/fp/template/{ => modules}/category.jst (100%) rename lib/fp/template/{ => modules}/convert.jst (100%) rename lib/fp/template/{ => modules}/fp.jst (100%) rename lib/fp/template/{ => modules}/module.jst (100%) rename lib/fp/template/{ => modules}/thru.jst (100%) diff --git a/lib/fp/build-modules.js b/lib/fp/build-modules.js index 39d188bd73..4462647dab 100644 --- a/lib/fp/build-modules.js +++ b/lib/fp/build-modules.js @@ -8,7 +8,7 @@ var _ = require('lodash'), var mapping = require('../../fp/_mapping'); -var templatePath = path.join(__dirname, 'template'); +var templatePath = path.join(__dirname, 'template/modules'); var template = _.transform(glob.sync(path.join(templatePath, '*.jst')), function(result, filePath) { result[path.basename(filePath, '.jst')] = _.template(fs.readFileSync(filePath)); diff --git a/lib/fp/template/doc/wiki.jst b/lib/fp/template/doc/wiki.jst new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/lib/fp/template/doc/wiki.jst @@ -0,0 +1 @@ + diff --git a/lib/fp/template/_util.jst b/lib/fp/template/modules/_util.jst similarity index 100% rename from lib/fp/template/_util.jst rename to lib/fp/template/modules/_util.jst diff --git a/lib/fp/template/alias.jst b/lib/fp/template/modules/alias.jst similarity index 100% rename from lib/fp/template/alias.jst rename to lib/fp/template/modules/alias.jst diff --git a/lib/fp/template/category.jst b/lib/fp/template/modules/category.jst similarity index 100% rename from lib/fp/template/category.jst rename to lib/fp/template/modules/category.jst diff --git a/lib/fp/template/convert.jst b/lib/fp/template/modules/convert.jst similarity index 100% rename from lib/fp/template/convert.jst rename to lib/fp/template/modules/convert.jst diff --git a/lib/fp/template/fp.jst b/lib/fp/template/modules/fp.jst similarity index 100% rename from lib/fp/template/fp.jst rename to lib/fp/template/modules/fp.jst diff --git a/lib/fp/template/module.jst b/lib/fp/template/modules/module.jst similarity index 100% rename from lib/fp/template/module.jst rename to lib/fp/template/modules/module.jst diff --git a/lib/fp/template/thru.jst b/lib/fp/template/modules/thru.jst similarity index 100% rename from lib/fp/template/thru.jst rename to lib/fp/template/modules/thru.jst From 40ff04911eee49cbca5e28929ff5e96e0395034e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Thu, 11 Feb 2016 23:23:29 -0800 Subject: [PATCH 36/79] Remove unneeded `copyArray` from `baseMergeDeep`. --- lodash.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lodash.js b/lodash.js index 5dafbfa1cf..93e3a9edba 100644 --- a/lodash.js +++ b/lodash.js @@ -3074,7 +3074,7 @@ newValue = srcValue; if (isArray(srcValue) || isTypedArray(srcValue)) { if (isArray(objValue)) { - newValue = srcIndex ? copyArray(objValue) : objValue; + newValue = objValue; } else if (isArrayLikeObject(objValue)) { newValue = copyArray(objValue); From 8ee7ffb2ab3cd07c08cd68c980292892c113d3b0 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 00:03:39 -0800 Subject: [PATCH 37/79] Add more currying to fp tests. --- test/test-fp.js | 80 ++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/test/test-fp.js b/test/test-fp.js index 397cdfbfe2..5cccbc64af 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -147,7 +147,7 @@ value = _.clone(array); remove = convert('remove', _.remove, { 'rearg': false }); - actual = remove(value, predicate); + actual = remove(value)(predicate); assert.deepEqual(value, [1, 2, 3, 4]); assert.deepEqual(actual, [1, 3]); @@ -351,20 +351,20 @@ var array = ['a', 'b', 'c'], other = ['b', 'b', 'd'], object = { 'a': 1, 'b': 2, 'c': 2 }, - actual = fp.difference(array, other); + actual = fp.difference(array)(other); assert.deepEqual(actual, ['a', 'c'], 'fp.difference'); - actual = fp.includes('b', array); + actual = fp.includes('b')(array); assert.strictEqual(actual, true, 'fp.includes'); - actual = fp.intersection(other, array); + actual = fp.intersection(other)(array); assert.deepEqual(actual, ['b'], 'fp.intersection'); - actual = fp.omit(other, object); + actual = fp.omit(other)(object); assert.deepEqual(actual, { 'a': 1, 'c': 2 }, 'fp.omit'); - actual = fp.union(other, array); + actual = fp.union(other)(array); assert.deepEqual(actual, ['a', 'b', 'c', 'd'], 'fp.union'); actual = fp.uniq(other); @@ -373,13 +373,13 @@ actual = fp.uniqBy(_.identity, other); assert.deepEqual(actual, ['b', 'd'], 'fp.uniqBy'); - actual = fp.without('b', array); + actual = fp.without('b')(array); assert.deepEqual(actual, ['a', 'c'], 'fp.without'); - actual = fp.xor(other, array); + actual = fp.xor(other)(array); assert.deepEqual(actual, ['a', 'c', 'd'], 'fp.xor'); - actual = fp.pull('b', array); + actual = fp.pull('b')(array); assert.deepEqual(actual, ['a', 'c'], 'fp.pull'); }); }()); @@ -415,14 +415,14 @@ args = undefined; reduce(function() { args || (args = slice.call(arguments)); - })(0, array); + })(0)(array); assert.deepEqual(args, [0, 1]); args = undefined; reduce(function() { args || (args = slice.call(arguments)); - })(0, object); + })(0)(object); assert.deepEqual(args, isFIFO ? [0, 1] : [0, 2]); }); @@ -476,7 +476,7 @@ Foo.prototype = { 'b': 2 }; var value = _.clone(object), - actual = fp.assign(value, { 'b': 2 }); + actual = fp.assign(value)({ 'b': 2 }); assert.deepEqual(value, object, 'fp.assign'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assign'); @@ -484,13 +484,13 @@ value = _.clone(object); actual = fp.assignWith(function(objValue, srcValue) { return srcValue; - }, value, { 'b': 2 }); + })(value)({ 'b': 2 }); assert.deepEqual(value, object, 'fp.assignWith'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignWith'); value = _.clone(object); - actual = fp.assignIn(value, new Foo); + actual = fp.assignIn(value)(new Foo); assert.deepEqual(value, object, 'fp.assignIn'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignIn'); @@ -498,25 +498,25 @@ value = _.clone(object); actual = fp.assignInWith(function(objValue, srcValue) { return srcValue; - }, value, new Foo); + })(value)(new Foo); assert.deepEqual(value, object, 'fp.assignInWith'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.assignInWith'); value = _.clone(object); - actual = fp.defaults({ 'a': 2, 'b': 2 }, value); + actual = fp.defaults({ 'a': 2, 'b': 2 })(value); assert.deepEqual(value, object, 'fp.defaults'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.defaults'); value = _.cloneDeep(deepObject); - actual = fp.defaultsDeep({ 'a': { 'c': 4, 'd': 4 } }, deepObject); + actual = fp.defaultsDeep({ 'a': { 'c': 4, 'd': 4 } })(deepObject); assert.deepEqual(value, { 'a': { 'b': 2, 'c': 3 } }, 'fp.defaultsDeep'); assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3, 'd': 4 } }, 'fp.defaultsDeep'); value = _.clone(object); - actual = fp.extend(value, new Foo); + actual = fp.extend(value)(new Foo); assert.deepEqual(value, object, 'fp.extend'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.extend'); @@ -524,19 +524,19 @@ value = _.clone(object); actual = fp.extendWith(function(objValue, srcValue) { return srcValue; - }, value, new Foo); + })(value)(new Foo); assert.deepEqual(value, object, 'fp.extendWith'); assert.deepEqual(actual, { 'a': 1, 'b': 2 }, 'fp.extendWith'); value = _.clone(array); - actual = fp.fill(1, 2, '*', value); + actual = fp.fill(1)(2)('*')(value); assert.deepEqual(value, array, 'fp.fill'); assert.deepEqual(actual, [1, '*', 3], 'fp.fill'); value = _.cloneDeep(deepObject); - actual = fp.merge(value, { 'a': { 'd': 4 } }); + actual = fp.merge(value)({ 'a': { 'd': 4 } }); assert.deepEqual(value, { 'a': { 'b': 2, 'c': 3 } }, 'fp.merge'); assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3, 'd': 4 } }, 'fp.merge'); @@ -554,19 +554,19 @@ assert.deepEqual(actual, { 'a': { 'b': [1, 2, 3], 'c': 3 } }, 'fp.mergeWith'); value = _.clone(array); - actual = fp.pull(2, value); + actual = fp.pull(2)(value); assert.deepEqual(value, array, 'fp.pull'); assert.deepEqual(actual, [1, 3], 'fp.pull'); value = _.clone(array); - actual = fp.pullAll([1, 3], value); + actual = fp.pullAll([1, 3])(value); assert.deepEqual(value, array, 'fp.pullAll'); assert.deepEqual(actual, [2], 'fp.pullAll'); value = _.clone(array); - actual = fp.pullAt([0, 2], value); + actual = fp.pullAt([0, 2])(value); assert.deepEqual(value, array, 'fp.pullAt'); assert.deepEqual(actual, [2], 'fp.pullAt'); @@ -574,7 +574,7 @@ value = _.clone(array); actual = fp.remove(function(value) { return value === 2; - }, value); + })(value); assert.deepEqual(value, array, 'fp.remove'); assert.deepEqual(actual, [1, 3], 'fp.remove'); @@ -586,19 +586,19 @@ assert.deepEqual(actual, [3, 2, 1], 'fp.reverse'); value = _.cloneDeep(deepObject); - actual = fp.set('a.b', 3, value); + actual = fp.set('a.b')(3)(value); assert.deepEqual(value, deepObject, 'fp.set'); assert.deepEqual(actual, { 'a': { 'b': 3, 'c': 3 } }, 'fp.set'); value = _.cloneDeep(deepObject); - actual = fp.setWith(Object, 'd.e', 4, value); + actual = fp.setWith(Object)('d.e')(4)(value); assert.deepEqual(value, deepObject, 'fp.setWith'); assert.deepEqual(actual, { 'a': { 'b': 2, 'c': 3 }, 'd': { 'e': 4 } }, 'fp.setWith'); value = _.cloneDeep(deepObject); - actual = fp.unset('a.b', value); + actual = fp.unset('a.b')(value); assert.deepEqual(value, deepObject, 'fp.unset'); assert.deepEqual(actual, { 'a': { 'c': 3 } }, 'fp.set'); @@ -655,7 +655,7 @@ fp.assignWith(function() { args || (args = _.map(arguments, _.cloneDeep)); - }, value, { 'b': 2 }); + })(value)({ 'b': 2 }); assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }], 'fp.assignWith'); @@ -664,7 +664,7 @@ fp.extendWith(function() { args || (args = _.map(arguments, _.cloneDeep)); - }, value, { 'b': 2 }); + })(value)({ 'b': 2 }); assert.deepEqual(args, [undefined, 2, 'b', { 'a': 1 }, { 'b': 2 }], 'fp.extendWith'); @@ -676,7 +676,7 @@ fp.mergeWith(function() { args || (args = _.map(arguments, _.cloneDeep)); - }, value, { 'a': [2, 3] }); + })(value)({ 'a': [2, 3] }); args[5] = _.omitBy(args[5], _.isFunction); assert.deepEqual(args, expected, 'fp.mergeWith'); @@ -686,7 +686,7 @@ fp.setWith(function() { args || (args = _.map(arguments, _.cloneDeep)); - }, 'b.c', 2, value); + })('b.c')(2)(value); assert.deepEqual(args, [undefined, 'b', { 'a': 1 }], 'fp.setWith'); }); @@ -731,7 +731,7 @@ QUnit.test('`_.' + methodName + '` should accept an `arity` param', function(assert) { assert.expect(1); - var actual = func(1, function(a, b) { return [a, b]; })('a'); + var actual = func(1)(function(a, b) { return [a, b]; })('a'); assert.deepEqual(actual, ['a', undefined]); }); }); @@ -763,7 +763,7 @@ var extend = convert('extend', _.extend), value = _.clone(object), - actual = extend(value, new Foo); + actual = extend(value)(new Foo); assert.deepEqual(value, object); assert.deepEqual(actual, { 'a': 1, 'b': 2 }); @@ -876,7 +876,7 @@ QUnit.test('should return a iteratee with capped params', function(assert) { assert.expect(1); - var func = fp.iteratee(function(a, b, c) { return [a, b, c]; }, undefined, 3); + var func = fp.iteratee(function(a, b, c) { return [a, b, c]; }, 3); assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]); }); @@ -884,7 +884,7 @@ assert.expect(1); var iteratee = convert('iteratee', _.iteratee), - func = iteratee(function(a, b, c) { return [a, b, c]; }, undefined, 3); + func = iteratee(function(a, b, c) { return [a, b, c]; }, 3); assert.deepEqual(func(1, 2, 3), [1, undefined, undefined]); }); @@ -1110,7 +1110,7 @@ func(function() { args || (args = slice.call(arguments)); - })(0, array); + })(0)(array); assert.deepEqual(args, isReduce ? [0, 1] : [0, 3]); }); @@ -1128,7 +1128,7 @@ func(function() { args || (args = slice.call(arguments)); - })(0, object); + })(0)(object); assert.deepEqual(args, expected); }); @@ -1219,7 +1219,7 @@ QUnit.test('should zip together two arrays', function(assert) { assert.expect(1); - assert.deepEqual(fp.zip([1, 2], [3, 4]), [[1, 3], [2, 4]]); + assert.deepEqual(fp.zip([1, 2])([3, 4]), [[1, 3], [2, 4]]); }); }()); @@ -1231,7 +1231,7 @@ QUnit.test('should zip together key/value arrays into an object', function(assert) { assert.expect(1); - assert.deepEqual(fp.zipObject(['a', 'b'], [1, 2]), { 'a': 1, 'b': 2 }); + assert.deepEqual(fp.zipObject(['a', 'b'])([1, 2]), { 'a': 1, 'b': 2 }); }); }()); From d6f6007692393445a1e66ab1eb48eee1d9eb519c Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 00:23:56 -0800 Subject: [PATCH 38/79] Add wiki link to "Further Reading" section of readme. [ci skip] --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ef02bc796f..4a381f3bee 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,6 @@ Create [custom builds](https://lodash.com/custom-builds) with only the features ## Further Reading - * [Build Differences](https://github.com/lodash/lodash/wiki/Build-Differences) - * [Changelog](https://github.com/lodash/lodash/wiki/Changelog) - * [Contributing & Feature Requests](https://github.com/lodash/lodash/blob/master/CONTRIBUTING.md) - * [FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) + * [Contributing](https://github.com/lodash/lodash/blob/master/CONTRIBUTING.md) * [Release Notes](https://github.com/lodash/lodash/releases/tag/4.0.0) - * [Roadmap](https://github.com/lodash/lodash/wiki/Roadmap) - * [More Resources](https://github.com/lodash/lodash/wiki/Resources) + * [Wiki](https://github.com/lodash/lodash/wiki) From a055b0a04f84a90aade0a4b718260823caacf49e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 00:04:16 -0800 Subject: [PATCH 39/79] Fix fp rearg order for `zipWith`. --- fp/_mapping.js | 3 ++- test/test-fp.js | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fp/_mapping.js b/fp/_mapping.js index d3c65fbaa2..57fbf28e5f 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -137,7 +137,8 @@ exports.methodRearg = { 'pullAllBy': [2, 1, 0], 'setWith': [3, 1, 2, 0], 'sortedIndexBy': [2, 1, 0], - 'sortedLastIndexBy': [2, 1, 0] + 'sortedLastIndexBy': [2, 1, 0], + 'zipWith': [1, 2, 0] }; /** Used to map method names to spread configs. */ diff --git a/test/test-fp.js b/test/test-fp.js index 5cccbc64af..4b2f7b77d7 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -1237,6 +1237,25 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('fp.zipWith'); + + (function() { + QUnit.test('should zip arrays combining grouped elements with `iteratee`', function(assert) { + assert.expect(1); + + var array1 = [1, 2, 3], + array2 = [4, 5, 6]; + + var actual = fp.zipWith(function(a, b) { + return a + b; + })(array1)(array2); + + assert.deepEqual(actual, [5, 7, 9]); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.config.asyncRetries = 10; QUnit.config.hidepassed = true; From 0bead0c69af6d9e6baa5e81963ebf33e58df8bf9 Mon Sep 17 00:00:00 2001 From: Jeroen Engels Date: Fri, 12 Feb 2016 11:47:30 +0100 Subject: [PATCH 40/79] Update closed issue link in contributing.md to link to enhancement issues. [ci skip] --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd2b148770..d55dd8cfbc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,7 +14,7 @@ Feature requests are always welcome. They should be submitted in the the expected behavior & use case, where they’ll remain closed until sufficient interest has been shown by the community. Before submitting a request, please search for similar ones in the -[closed issues](https://github.com/lodash/lodash/issues?q=is%3Aissue+is%3Aclosed). +[closed issues](https://github.com/lodash/lodash/issues?q=is%3Aissue+is%3Aclosed+label%3Aenhancement). ## Pull Requests From b3ebb3c3d3cf394113d8e9c05578161e7f1cdeb4 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 14:11:42 -0800 Subject: [PATCH 41/79] Add `_.fromPairs` to mention to `_.toPairs` and `_.toPairsIn`. [ci skip] --- lodash.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lodash.js b/lodash.js index 93e3a9edba..9b35f92ffa 100644 --- a/lodash.js +++ b/lodash.js @@ -11711,7 +11711,8 @@ } /** - * Creates an array of own enumerable key-value pairs for `object`. + * Creates an array of own enumerable key-value pairs for `object` which + * can be consumed by `_.fromPairs`. * * @static * @memberOf _ @@ -11735,7 +11736,8 @@ } /** - * Creates an array of own and inherited enumerable key-value pairs for `object`. + * Creates an array of own and inherited enumerable key-value pairs for + * `object` which can be consumed by `_.fromPairs`. * * @static * @memberOf _ From df0ecd2a930895d951294ea31a5f40e03dd5bf6d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 15:47:27 -0800 Subject: [PATCH 42/79] Ensure `_.isError` works with subclasses values. [closes #1994] --- lodash.js | 9 ++++++--- test/test.js | 57 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lodash.js b/lodash.js index 9b35f92ffa..b2a4210288 100644 --- a/lodash.js +++ b/lodash.js @@ -9761,8 +9761,11 @@ * // => false */ function isError(value) { - return isObjectLike(value) && - typeof value.message == 'string' && objectToString.call(value) == errorTag; + if (!isObjectLike(value)) { + return false; + } + var Ctor = value.constructor; + return typeof Ctor == 'function' && objectToString.call(Ctor.prototype) == errorTag; } /** @@ -13121,7 +13124,7 @@ try { return apply(func, undefined, args); } catch (e) { - return isObject(e) ? e : new Error(e); + return isError(e) ? e : new Error(e); } }); diff --git a/test/test.js b/test/test.js index b340daa94c..5680d47220 100644 --- a/test/test.js +++ b/test/test.js @@ -352,6 +352,32 @@ function(chr) { return /\s/.exec(chr); }) .join(''); + /** + * The custom error constructor. + * + * @private + * @param {string} message The error message. + * @returns {Object} Returns the new error object instance. + */ + function CustomError(message) { + this.name = 'CustomError'; + this.message = message; + } + + CustomError.prototype = lodashStable.create(Error.prototype); + + /** + * Removes all own enumerable properties from a given object. + * + * @private + * @param {Object} object The object to empty. + */ + function emptyObject(object) { + lodashStable.forOwn(object, function(value, key, object) { + delete object[key]; + }); + } + /** * Extracts the unwrapped value from its wrapper. * @@ -375,18 +401,6 @@ return result; } - /** - * Removes all own enumerable properties from a given object. - * - * @private - * @param {Object} object The object to empty. - */ - function emptyObject(object) { - lodashStable.forOwn(object, function(value, key, object) { - delete object[key]; - }); - } - /** * Sets a non-enumerable property value on `object`. * @@ -1519,13 +1533,6 @@ QUnit.test('should preserve custom errors', function(assert) { assert.expect(1); - function CustomError(message) { - this.name = 'CustomError'; - this.message = message; - } - - CustomError.prototype = lodashStable.create(Error.prototype); - var actual = _.attempt(function() { throw new CustomError('x'); }); assert.ok(actual instanceof CustomError); }); @@ -9219,6 +9226,12 @@ assert.deepEqual(actual, expected); }); + QUnit.test('should return `true` for subclassed values', function(assert) { + assert.expect(1); + + assert.strictEqual(_.isError(new CustomError('x')), true); + }); + QUnit.test('should return `false` for non error objects', function(assert) { assert.expect(12); @@ -11012,11 +11025,11 @@ (function() { QUnit.test('should return `false` for subclassed values', function(assert) { - assert.expect(8); + assert.expect(7); var funcs = [ - 'isArray', 'isBoolean', 'isDate', 'isError', - 'isFunction', 'isNumber', 'isRegExp', 'isString' + 'isArray', 'isBoolean', 'isDate', 'isFunction', + 'isNumber', 'isRegExp', 'isString' ]; lodashStable.each(funcs, function(methodName) { From bf9dcfe89c629f6415aa742b72a289e6f14a7c0e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 15:59:19 -0800 Subject: [PATCH 43/79] Add jsdoc `constructor` tags. [ci skip] --- lodash.js | 5 +++++ test/test.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lodash.js b/lodash.js index b2a4210288..f853a275e9 100644 --- a/lodash.js +++ b/lodash.js @@ -1569,6 +1569,7 @@ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. * * @private + * @constructor * @param {*} value The value to wrap. */ function LazyWrapper(value) { @@ -1683,6 +1684,7 @@ * Creates an hash object. * * @private + * @constructor * @returns {Object} Returns the new hash object. */ function Hash() {} @@ -1745,6 +1747,7 @@ * Creates a map cache object to store key-value pairs. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function MapCache(values) { @@ -1849,6 +1852,7 @@ * Creates a set cache object to store unique values. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { @@ -1907,6 +1911,7 @@ * Creates a stack cache object to store key-value pairs. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function Stack(values) { diff --git a/test/test.js b/test/test.js index 5680d47220..0fd03965fa 100644 --- a/test/test.js +++ b/test/test.js @@ -353,11 +353,11 @@ .join(''); /** - * The custom error constructor. + * Creates a custom error object. * * @private + * @constructor * @param {string} message The error message. - * @returns {Object} Returns the new error object instance. */ function CustomError(message) { this.name = 'CustomError'; From de0f936e920102243342c750c588c35e1cf061cc Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 12 Feb 2016 22:49:49 -0800 Subject: [PATCH 44/79] Ensure fp `convert` works with category modules. --- fp/_baseConvert.js | 37 ++++++++++++++++++++-------------- test/test-fp.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index 96cc185f47..cb8975b2b8 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -18,16 +18,20 @@ var mapping = require('./_mapping'), * @returns {Function|Object} Returns the converted function or object. */ function baseConvert(util, name, func, options) { - var isLib = typeof name == 'function'; - if (isLib) { + var setPlaceholder, + isLib = typeof name == 'function', + isObj = name === Object(name); + + if (isObj) { options = func; func = name; name = undefined; } - options || (options = {}); if (func == null) { throw new TypeError; } + options || (options = {}); + var config = { 'cap': 'cap' in options ? options.cap : true, 'curry': 'curry' in options ? options.curry : true, @@ -38,7 +42,7 @@ function baseConvert(util, name, func, options) { var forceRearg = ('rearg' in options) && options.rearg; - var _ = isLib ? func : { + var helpers = isLib ? func : { 'ary': util.ary, 'cloneDeep': util.cloneDeep, 'curry': util.curry, @@ -50,14 +54,14 @@ function baseConvert(util, name, func, options) { 'spread': util.spread }; - var ary = _.ary, - cloneDeep = _.cloneDeep, - curry = _.curry, - each = _.forEach, - isFunction = _.isFunction, - keys = _.keys, - rearg = _.rearg, - spread = _.spread; + var ary = helpers.ary, + cloneDeep = helpers.cloneDeep, + curry = helpers.curry, + each = helpers.forEach, + isFunction = helpers.isFunction, + keys = helpers.keys, + rearg = helpers.rearg, + spread = helpers.spread; var baseArity = function(func, n) { return n == 2 @@ -225,16 +229,16 @@ function baseConvert(util, name, func, options) { result || (result = wrapped); if (mapping.placeholder[name]) { + setPlaceholder = true; func.placeholder = result.placeholder = placeholder; } return result; }; - if (!isLib) { + if (!isObj) { return wrap(name, func); } - // Add placeholder. - _.placeholder = placeholder; + var _ = func; // Iterate over methods for the current ary cap. var pairs = []; @@ -252,6 +256,9 @@ function baseConvert(util, name, func, options) { _[pair[0]] = pair[1]; }); + if (setPlaceholder) { + _.placeholder = placeholder; + } // Wrap the lodash method and its aliases. each(keys(_), function(key) { each(mapping.realToAlias[key] || [], function(alias) { diff --git a/test/test-fp.js b/test/test-fp.js index 4b2f7b77d7..ace1cd6efb 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -103,6 +103,40 @@ 'rearg': false }; + QUnit.test('should work when given an object', function(assert) { + assert.expect(2); + + var array = [1, 2, 3, 4], + lodash = convert({ 'remove': _.remove }); + + var actual = lodash.remove(function(n) { + return n % 2 == 0; + })(array); + + assert.deepEqual(array, [1, 2, 3, 4]); + assert.deepEqual(actual, [1, 3]); + }); + + QUnit.test('should only add a `placeholder` property if needed', function(assert) { + assert.expect(2); + + var methodNames = _.keys(mapping.placeholder), + expected = _.map(methodNames, _.constant(true)); + + var actual = _.map(methodNames, function(methodName) { + var object = {}; + object[methodName] = _[methodName]; + + var lodash = convert(object); + return methodName in lodash; + }); + + assert.deepEqual(actual, expected); + + var lodash = convert({ 'add': _.add }); + assert.notOk('placeholder' in lodash); + }); + QUnit.test('should accept an `options` argument', function(assert) { assert.expect(3); @@ -203,6 +237,21 @@ assert.deepEqual(actual, [1, 3]); assert.deepEqual(lodash.remove(), []); }); + + QUnit.test('should work when given an object and `options`', function(assert) { + assert.expect(3); + + var array = [1, 2, 3, 4], + lodash = convert({ 'remove': _.remove }, allFalseOptions); + + var actual = lodash.remove(array, function(n, index) { + return index % 2 == 0; + }); + + assert.deepEqual(array, [2, 4]); + assert.deepEqual(actual, [1, 3]); + assert.deepEqual(lodash.remove(), []); + }); }()); /*--------------------------------------------------------------------------*/ From af46ead30d273f59e7b6839f63bdd26075a498f0 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 02:01:46 -0800 Subject: [PATCH 45/79] Fix `caller` access in strict mode es6 modules. --- test/test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 0fd03965fa..438fb53b35 100644 --- a/test/test.js +++ b/test/test.js @@ -483,7 +483,7 @@ 'enumerable': true, 'get': function get() { var caller = get.caller, - name = caller.name; + name = caller ? caller.name : ''; if (!(name == 'runInContext' || name.length == 1 || /\b_\.isBuffer\b/.test(caller))) { return Buffer; From 4a390bca1c8c00b4d3ea481476785ebb506e799a Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 02:18:15 -0800 Subject: [PATCH 46/79] Update tests for es6. --- test/asset/test-ui.js | 4 ++-- test/test.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/asset/test-ui.js b/test/asset/test-ui.js index e8882dcb78..24f087a480 100644 --- a/test/asset/test-ui.js +++ b/test/asset/test-ui.js @@ -154,13 +154,13 @@ ui.isForeign = RegExp('^(\\w+:)?//').test(build); // Used to indicate testing a modularized build. - ui.isModularize = /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test([location.pathname, location.search]); + ui.isModularize = /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test([location.pathname, location.search]); // Used to indicate testing in Sauce Labs' automated test cloud. ui.isSauceLabs = location.port == '9001'; // Used to indicate that lodash is in strict mode. - ui.isStrict = /\bes6?\b/.test([location.pathname, location.search]); + ui.isStrict = /\bes\b/.test([location.pathname, location.search]); ui.urlParams = { 'build': build, 'loader': loader }; ui.timing = { 'loadEventEnd': 0 }; diff --git a/test/test.js b/test/test.js index 438fb53b35..7ece530815 100644 --- a/test/test.js +++ b/test/test.js @@ -131,8 +131,8 @@ var ui = root.ui || (root.ui = { 'buildPath': filePath, 'loaderPath': '', - 'isModularize': /\b(?:amd|commonjs|es6?|node|npm|(index|main)\.js)\b/.test(filePath), - 'isStrict': /\bes6?\b/.test(filePath), + 'isModularize': /\b(?:amd|commonjs|es|node|npm|(index|main)\.js)\b/.test(filePath), + 'isStrict': /\bes\b/.test(filePath), 'urlParams': {} }); @@ -8165,7 +8165,7 @@ QUnit.test('should return `false` if `Buffer` is not defined', function(assert) { assert.expect(1); - if (Buffer && lodashBizarro) { + if (!isStrict && Buffer && lodashBizarro) { assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false); } else { From 26265c011ad8f7c3ff38febe1f36d3aaf8d47ab0 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 02:18:37 -0800 Subject: [PATCH 47/79] Fix failing `_.isError` test in phantomjs. --- lodash.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lodash.js b/lodash.js index f853a275e9..d54f8ffef9 100644 --- a/lodash.js +++ b/lodash.js @@ -9770,7 +9770,8 @@ return false; } var Ctor = value.constructor; - return typeof Ctor == 'function' && objectToString.call(Ctor.prototype) == errorTag; + return (objectToString.call(value) == errorTag) || + (typeof Ctor == 'function' && objectToString.call(Ctor.prototype) == errorTag); } /** From 5a336403f9b147bb22d2b0d864f4055f4fabf6cc Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 08:31:04 -0800 Subject: [PATCH 48/79] Fix fp browser test fails. --- test/test-fp.js | 67 ++++++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/test/test-fp.js b/test/test-fp.js index ace1cd6efb..25de28dafe 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -106,35 +106,45 @@ QUnit.test('should work when given an object', function(assert) { assert.expect(2); - var array = [1, 2, 3, 4], - lodash = convert({ 'remove': _.remove }); + if (!document) { + var array = [1, 2, 3, 4], + lodash = convert({ 'remove': _.remove }); - var actual = lodash.remove(function(n) { - return n % 2 == 0; - })(array); + var actual = lodash.remove(function(n) { + return n % 2 == 0; + })(array); - assert.deepEqual(array, [1, 2, 3, 4]); - assert.deepEqual(actual, [1, 3]); + assert.deepEqual(array, [1, 2, 3, 4]); + assert.deepEqual(actual, [1, 3]); + } + else { + skipTest(assert, 2); + } }); QUnit.test('should only add a `placeholder` property if needed', function(assert) { assert.expect(2); - var methodNames = _.keys(mapping.placeholder), - expected = _.map(methodNames, _.constant(true)); + if (!document) { + var methodNames = _.keys(mapping.placeholder), + expected = _.map(methodNames, _.constant(true)); - var actual = _.map(methodNames, function(methodName) { - var object = {}; - object[methodName] = _[methodName]; + var actual = _.map(methodNames, function(methodName) { + var object = {}; + object[methodName] = _[methodName]; - var lodash = convert(object); - return methodName in lodash; - }); + var lodash = convert(object); + return methodName in lodash; + }); - assert.deepEqual(actual, expected); + assert.deepEqual(actual, expected); - var lodash = convert({ 'add': _.add }); - assert.notOk('placeholder' in lodash); + var lodash = convert({ 'add': _.add }); + assert.notOk('placeholder' in lodash); + } + else { + skipTest(assert, 2); + } }); QUnit.test('should accept an `options` argument', function(assert) { @@ -241,16 +251,21 @@ QUnit.test('should work when given an object and `options`', function(assert) { assert.expect(3); - var array = [1, 2, 3, 4], - lodash = convert({ 'remove': _.remove }, allFalseOptions); + if (!document) { + var array = [1, 2, 3, 4], + lodash = convert({ 'remove': _.remove }, allFalseOptions); - var actual = lodash.remove(array, function(n, index) { - return index % 2 == 0; - }); + var actual = lodash.remove(array, function(n, index) { + return index % 2 == 0; + }); - assert.deepEqual(array, [2, 4]); - assert.deepEqual(actual, [1, 3]); - assert.deepEqual(lodash.remove(), []); + assert.deepEqual(array, [2, 4]); + assert.deepEqual(actual, [1, 3]); + assert.deepEqual(lodash.remove(), []); + } + else { + skipTest(assert, 3); + } }); }()); From 13e4b959a430de89942b2afedafe9798629de896 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 08:32:47 -0800 Subject: [PATCH 49/79] Rename `skipTest` to `skipAssert`. --- test/test-fp.js | 10 +- test/test.js | 598 ++++++++++++++++++++++++------------------------ 2 files changed, 304 insertions(+), 304 deletions(-) diff --git a/test/test-fp.js b/test/test-fp.js index 25de28dafe..9a29fc8661 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -79,7 +79,7 @@ * @param {Object} assert The QUnit assert object. * @param {number} [count=1] The number of tests to skip. */ - function skipTest(assert, count) { + function skipAssert(assert, count) { count || (count = 1); while (count--) { assert.ok(true, 'test skipped'); @@ -118,7 +118,7 @@ assert.deepEqual(actual, [1, 3]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -143,7 +143,7 @@ assert.notOk('placeholder' in lodash); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -264,7 +264,7 @@ assert.deepEqual(lodash.remove(), []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }()); @@ -889,7 +889,7 @@ assert.strictEqual(mapCount, 5, 'mapCount'); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }); diff --git a/test/test.js b/test/test.js index 7ece530815..9758476cc3 100644 --- a/test/test.js +++ b/test/test.js @@ -434,7 +434,7 @@ * @param {Object} assert The QUnit assert object. * @param {number} [count=1] The number of tests to skip. */ - function skipTest(assert, count) { + function skipAssert(assert, count) { count || (count = 1); while (count--) { assert.ok(true, 'test skipped'); @@ -689,7 +689,7 @@ assert.strictEqual((lodashModule || {}).moduleName, 'lodash'); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -699,7 +699,7 @@ if (amd && lodashStable.includes(ui.loaderPath, 'requirejs')) { assert.strictEqual((shimmedModule || {}).moduleName, 'shimmed'); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -710,7 +710,7 @@ assert.strictEqual((underscoreModule || {}).moduleName, 'underscore'); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -736,7 +736,7 @@ attempt(); } else { - skipTest(assert); + skipAssert(assert); done(); } }); @@ -748,7 +748,7 @@ assert.notOk('_method' in lodashBizarro); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -837,7 +837,7 @@ assert.deepEqual(actual, [], label); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -863,7 +863,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -881,7 +881,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -907,7 +907,7 @@ assert.strictEqual(func(1, 'a', new Foo), true); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -921,7 +921,7 @@ assert.strictEqual(func(1, 'b', object), false); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -933,7 +933,7 @@ assert.strictEqual(func(NaN, 'a', { 'a': NaN }), true); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -949,7 +949,7 @@ assert.strictEqual(actual, false, message || ''); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -973,7 +973,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -989,7 +989,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -1008,7 +1008,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -1054,7 +1054,7 @@ assert.strictEqual(_(1).add(2), 3); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -1065,7 +1065,7 @@ assert.ok(_(1).chain().add(2) instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -1196,7 +1196,7 @@ assert.strictEqual(includes('b')(array, 2), true); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -1445,7 +1445,7 @@ }); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); @@ -1470,7 +1470,7 @@ }); } else { - skipTest(assert, 8); + skipAssert(assert, 8); } }); @@ -1488,7 +1488,7 @@ assert.deepEqual(actual, _.at(indexObject, 0)); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }(1, 2, 3)); @@ -1550,7 +1550,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -1561,7 +1561,7 @@ assert.strictEqual(_(lodashStable.constant('x')).attempt(), 'x'); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -1572,7 +1572,7 @@ assert.ok(_(lodashStable.constant('x')).chain().attempt() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -1849,7 +1849,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -1866,7 +1866,7 @@ assert.deepEqual(actual, [object, 'a', 'b', 'c']); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -2079,7 +2079,7 @@ assert.strictEqual(_('foo bar')[methodName](), converted); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -2090,7 +2090,7 @@ assert.ok(_('foo bar').chain()[methodName]() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -2169,7 +2169,7 @@ assert.ok(actual instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -2182,7 +2182,7 @@ assert.strictEqual(wrapped.chain(), wrapped); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -2202,7 +2202,7 @@ assert.ok(_(array).chain().sortBy().head() instanceof _); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); @@ -2253,7 +2253,7 @@ }); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -2548,7 +2548,7 @@ assert.notStrictEqual(actual, arrayBuffer); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -2588,7 +2588,7 @@ assert.strictEqual(actual[0], isDeep ? 2 : 1); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -2648,11 +2648,11 @@ assert.strictEqual(func(object).a.b[symbol], object.a.b[symbol]); } else { - skipTest(assert); + skipAssert(assert); } } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -2670,7 +2670,7 @@ assert.notStrictEqual(actual, object); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -2681,7 +2681,7 @@ assert.strictEqual(func(symbol), symbol); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -2698,7 +2698,7 @@ } } else { - skipTest(assert); + skipAssert(assert); } }); @@ -2754,7 +2754,7 @@ assert.notStrictEqual(actual, object); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -2777,7 +2777,7 @@ assert.strictEqual(actual.length, array.length); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }); @@ -2797,7 +2797,7 @@ assert.deepEqual(func(value), expected); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }); @@ -2876,7 +2876,7 @@ assert.deepEqual(actual, [true, 1, 'a']); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -2890,7 +2890,7 @@ assert.deepEqual(actual, _.take(_.compact(_.slice(array, 1)).reverse())); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -2965,7 +2965,7 @@ assert.deepEqual(actual, [1, 2, 3]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -3270,7 +3270,7 @@ assert.ok(wrapped instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -3355,7 +3355,7 @@ assert.deepEqual(actual, _.take(_.filter(_.map(_.countBy(array), square), isEven))); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -4520,7 +4520,7 @@ assert.deepEqual(actual, _.dropRight(_.drop(_.dropRight(_.drop(_.filter(_.drop(array), predicate), 2))), 2)); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -4608,7 +4608,7 @@ assert.deepEqual(actual, _.drop(_.dropRight(_.drop(_.dropRight(_.filter(_.dropRight(array), predicate), 2))), 2)); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -4678,7 +4678,7 @@ assert.deepEqual(wrapped.value(), [1, 2]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -4750,7 +4750,7 @@ assert.strictEqual(wrapped.last(), _.last(expected)); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -4769,7 +4769,7 @@ assert.deepEqual(actual, array.slice(3)); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -5053,7 +5053,7 @@ assert.ok(pass); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -5218,7 +5218,7 @@ assert.strictEqual(actual, array); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }()); @@ -5346,7 +5346,7 @@ assert.strictEqual(_(array)[methodName](), expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -5357,7 +5357,7 @@ assert.ok(_(array).chain()[methodName]() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -5369,7 +5369,7 @@ assert.strictEqual(wrapped.__wrapped__, array); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -5388,7 +5388,7 @@ }); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -5438,7 +5438,7 @@ assert.strictEqual(actual, isFind ? 4 : square(LARGE_ARRAY_SIZE)); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }); @@ -5560,7 +5560,7 @@ }); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -5694,7 +5694,7 @@ assert.deepEqual(actual.value(), [1, 2, 3, [4], 5]); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }(1, 2, 3)); @@ -5782,7 +5782,7 @@ assert.strictEqual(mapCount, 5, 'mapCount'); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } _.filter = filter1; _.map = map1; @@ -5812,7 +5812,7 @@ assert.ok(wrapped instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6034,7 +6034,7 @@ assert.deepEqual(args, expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -6072,7 +6072,7 @@ assert.deepEqual(argsList, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6097,7 +6097,7 @@ assert.notOk(lodashStable.includes(keys, 'a')); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6115,7 +6115,7 @@ assert.ok(wrapped instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6132,7 +6132,7 @@ assert.notOk(actual instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -6147,7 +6147,7 @@ assert.notStrictEqual(actual, wrapped); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -6168,7 +6168,7 @@ assert.deepEqual(values, [1]); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6184,7 +6184,7 @@ assert.strictEqual(func(array, Boolean), array); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6217,7 +6217,7 @@ assert.notOk(isIteratedAsObject({ 'length': 0 })); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }); @@ -6246,7 +6246,7 @@ assert.strictEqual(count, 1); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6274,7 +6274,7 @@ assert.strictEqual(count, 1); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6369,7 +6369,7 @@ assert.notStrictEqual(actual, wrapped); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6410,7 +6410,7 @@ assert.ok(pass); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6499,7 +6499,7 @@ assert.deepEqual(values, [lodashStable.endsWith(methodName, 'Right') ? 3 : 1]); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -6518,7 +6518,7 @@ assert.strictEqual(values.length, 1); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -6602,7 +6602,7 @@ assert.deepEqual(actual, _.take(_.filter(_.map(_.fromPairs(array), square), isEven))); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -6713,7 +6713,7 @@ assert.deepEqual(actual, _.take(_.filter(lodashStable.map(_.groupBy(array), iteratee), predicate))); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -6844,7 +6844,7 @@ assert.strictEqual(func(object, 1), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -6966,7 +6966,7 @@ assert.strictEqual(_(array).head(), 1); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -6977,7 +6977,7 @@ assert.ok(_(array).chain().head() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -6989,7 +6989,7 @@ assert.strictEqual(wrapped.__wrapped__, array); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -7008,7 +7008,7 @@ }); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -7125,7 +7125,7 @@ assert.strictEqual(_(collection).includes(3), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -7136,7 +7136,7 @@ assert.ok(_(collection).chain().includes(3) instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -7336,7 +7336,7 @@ assert.deepEqual(values, array); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); }()); @@ -7483,7 +7483,7 @@ assert.deepEqual(wrapped.value(), [1, 2]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -7573,7 +7573,7 @@ assert.deepEqual(wrapped.value(), { '1': 'a', '2': 'b' }); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -7700,7 +7700,7 @@ assert.strictEqual(_(object).invoke('a'), 1); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -7712,7 +7712,7 @@ assert.ok(_(object).chain().invoke('a') instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -7826,7 +7826,7 @@ assert.deepEqual(actual.valueOf(), ['(A)', '(B)', '(C)']); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -7847,7 +7847,7 @@ assert.deepEqual(actual, [0]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -7898,7 +7898,7 @@ assert.strictEqual(_.isArguments(realm.arguments), true); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -7947,7 +7947,7 @@ assert.strictEqual(_.isArray(realm.array), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -7966,7 +7966,7 @@ assert.strictEqual(_.isArrayBuffer(arrayBuffer), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -8002,7 +8002,7 @@ assert.strictEqual(_.isArrayBuffer(realm.arrayBuffer), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8060,7 +8060,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8114,7 +8114,7 @@ assert.strictEqual(_.isBoolean(realm.boolean), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8133,7 +8133,7 @@ assert.strictEqual(_.isBuffer(new Buffer(2)), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -8169,7 +8169,7 @@ assert.strictEqual(lodashBizarro.isBuffer(new Buffer(2)), false); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8218,7 +8218,7 @@ assert.strictEqual(_.isDate(realm.date), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8280,7 +8280,7 @@ assert.strictEqual(_.isElement(realm.element), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8369,7 +8369,7 @@ assert.strictEqual(_({}).isEmpty(), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -8380,7 +8380,7 @@ assert.ok(_({}).chain().isEmpty() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -8726,7 +8726,7 @@ assert.strictEqual(_.isEqual(object1, object2), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -8802,7 +8802,7 @@ assert.strictEqual(_.isEqual(buffer1, buffer2), true); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -8876,7 +8876,7 @@ assert.strictEqual(_.isEqual(map1, map2), false); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -8913,7 +8913,7 @@ assert.strictEqual(_.isEqual(set1, set2), false); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -8957,7 +8957,7 @@ assert.strictEqual(_.isEqual({ 'a': 2 }, realm.object), false); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -8975,7 +8975,7 @@ } } else { - skipTest(assert); + skipAssert(assert); } }); @@ -9012,7 +9012,7 @@ assert.strictEqual(_.isEqual(_(actual), _(false)), true); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); }); @@ -9034,7 +9034,7 @@ assert.strictEqual(_.isEqual(object1, object2), false); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -9045,7 +9045,7 @@ assert.strictEqual(_('a').isEqual('a'), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -9056,7 +9056,7 @@ assert.ok(_('a').chain().isEqual('a') instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -9201,7 +9201,7 @@ assert.deepEqual(argsList, expected, index ? 'Set' : 'Map'); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -9269,7 +9269,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -9391,7 +9391,7 @@ if (document) { assert.strictEqual(_.isFunction(document.getElementsByTagName('body')), false); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -9406,7 +9406,7 @@ assert.strictEqual(_.isFunction(object), false); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -9418,7 +9418,7 @@ assert.strictEqual(_.isFunction(realm.function), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -9524,7 +9524,7 @@ assert.strictEqual(_.isMap(map), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -9561,7 +9561,7 @@ assert.strictEqual(_.isMap(realm.map), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -9743,7 +9743,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -9776,7 +9776,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -10024,7 +10024,7 @@ assert.deepEqual(argsList, expected, index ? 'Set' : 'Map'); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -10079,7 +10079,7 @@ assert.strictEqual(_.isNaN(realm.nan), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10099,7 +10099,7 @@ assert.strictEqual(_.isNative(func), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10107,7 +10107,7 @@ assert.strictEqual(_.isNative(body.cloneNode), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10142,13 +10142,13 @@ assert.strictEqual(_.isNative(realm.element.cloneNode), true); } else { - skipTest(assert); + skipAssert(assert); } if (realm.object) { assert.strictEqual(_.isNative(realm.object.valueOf), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10197,7 +10197,7 @@ assert.strictEqual(_.isNil(symbol), false); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10209,7 +10209,7 @@ assert.strictEqual(_.isNil(realm.undefined), true); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }(1, 2, 3)); @@ -10261,7 +10261,7 @@ assert.strictEqual(_.isNull(realm.null), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10314,7 +10314,7 @@ assert.strictEqual(_.isNumber(realm.number), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10351,13 +10351,13 @@ assert.strictEqual(_.isObject(body), true); } else { - skipTest(assert); + skipAssert(assert); } if (Symbol) { assert.strictEqual(_.isObject(Object(symbol)), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10381,7 +10381,7 @@ assert.strictEqual(_.isObject(realm.element), true); } else { - skipTest(assert); + skipAssert(assert); } if (realm.object) { assert.strictEqual(_.isObject(realm.boolean), true); @@ -10393,7 +10393,7 @@ assert.strictEqual(_.isObject(realm.string), true); } else { - skipTest(assert, 7); + skipAssert(assert, 7); } }); @@ -10460,7 +10460,7 @@ assert.strictEqual(_.isObjectLike(realm.string), true); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }(1, 2, 3)); @@ -10497,7 +10497,7 @@ assert.strictEqual(_.isPlainObject(object), true); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -10514,7 +10514,7 @@ element.valueOf = valueOf; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10524,7 +10524,7 @@ if (element) { assert.strictEqual(_.isPlainObject(element), false); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10559,7 +10559,7 @@ assert.strictEqual(_.isPlainObject(realm.object), true); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -10609,7 +10609,7 @@ assert.strictEqual(_.isRegExp(realm.regexp), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10628,7 +10628,7 @@ assert.strictEqual(_.isSet(set), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10665,7 +10665,7 @@ assert.strictEqual(_.isSet(realm.set), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10717,7 +10717,7 @@ assert.strictEqual(_.isString(realm.string), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10737,7 +10737,7 @@ assert.strictEqual(_.isSymbol(Object(symbol)), true); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -10772,7 +10772,7 @@ assert.strictEqual(_.isSymbol(realm.symbol), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10843,7 +10843,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10891,7 +10891,7 @@ assert.strictEqual(_.isUndefined(symbol), false); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10902,7 +10902,7 @@ assert.strictEqual(_.isUndefined(realm.undefined), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10921,7 +10921,7 @@ assert.strictEqual(_.isWeakMap(weakMap), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -10958,7 +10958,7 @@ assert.strictEqual(_.isWeakMap(realm.weakMap), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -10977,7 +10977,7 @@ assert.strictEqual(_.isWeakSet(weakSet), true); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11014,7 +11014,7 @@ assert.strictEqual(_.isWeakSet(realm.weakSet), true); } else { - skipTest(assert); + skipAssert(assert); } }); }(1, 2, 3)); @@ -11040,7 +11040,7 @@ if (objToString.call(object) == objectTag) { assert.strictEqual(_[methodName](object), false, '`_.' + methodName + '` returns `false`'); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -11068,7 +11068,7 @@ assert.ok(pass, '`_.' + methodName + '` should not error'); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -11292,7 +11292,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11305,7 +11305,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11318,7 +11318,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11331,7 +11331,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11344,7 +11344,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11359,7 +11359,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11372,7 +11372,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11385,7 +11385,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11398,7 +11398,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11411,7 +11411,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11424,7 +11424,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11437,7 +11437,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11450,7 +11450,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11463,7 +11463,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11476,7 +11476,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11489,7 +11489,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11502,7 +11502,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11515,7 +11515,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11528,7 +11528,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11541,7 +11541,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11556,7 +11556,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11569,7 +11569,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11582,7 +11582,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11595,7 +11595,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11610,7 +11610,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11626,7 +11626,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11639,7 +11639,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11652,7 +11652,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11667,7 +11667,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11682,7 +11682,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11695,7 +11695,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11708,7 +11708,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11721,7 +11721,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11739,7 +11739,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11752,7 +11752,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11765,7 +11765,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); @@ -11778,7 +11778,7 @@ _.iteratee = iteratee; } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -11805,7 +11805,7 @@ assert.strictEqual(wrapped.value(), array); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -11816,7 +11816,7 @@ assert.ok(_(array).chain().join('~') instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -11911,7 +11911,7 @@ assert.deepEqual(actual, _.take(_.filter(_.map(_.keyBy(array), square), isEven))); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -12114,7 +12114,7 @@ assert.strictEqual(_(array).last(), 4); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -12125,7 +12125,7 @@ assert.ok(_(array).chain().last() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -12137,7 +12137,7 @@ assert.strictEqual(wrapped.__wrapped__, array); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -12156,7 +12156,7 @@ }); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -12365,13 +12365,13 @@ if (isSorted) { assert.strictEqual(func(array, NaN, true), isIndexOf ? 2 : 3); - skipTest(assert, 3); + skipAssert(assert, 3); } else { assert.strictEqual(func(array, NaN), isIndexOf ? 1 : 5); assert.strictEqual(func(array, NaN, 2), isIndexOf ? 3 : 1); assert.strictEqual(func(array, NaN, -2), isIndexOf ? 5 : 3); - skipTest(assert); + skipAssert(assert); } }); @@ -12457,7 +12457,7 @@ assert.deepEqual(actual, ['body']); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -12488,7 +12488,7 @@ assert.ok(_(array).map(noop) instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -12535,7 +12535,7 @@ assert.deepEqual(args, expected); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }()); @@ -12655,7 +12655,7 @@ assert.ok(_(object)[methodName](noop) instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -12840,7 +12840,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -12870,7 +12870,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -13262,7 +13262,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -13292,7 +13292,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -13675,7 +13675,7 @@ assert.strictEqual(cache.has(key), true); } else { - skipTest(assert, 8); + skipAssert(assert, 8); } }); @@ -13686,7 +13686,7 @@ })); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -14038,7 +14038,7 @@ assert.ok(pass); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -14492,7 +14492,7 @@ assert.strictEqual(actual, 40); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -14586,7 +14586,7 @@ delete _.prototype.b; } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -14604,7 +14604,7 @@ delete _.prototype.a; } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -14699,7 +14699,7 @@ delete func.prototype.b; } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -14762,7 +14762,7 @@ delete func.prototype.b; } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -14784,7 +14784,7 @@ delete _.prototype.b; } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -14957,7 +14957,7 @@ root._ = oldDash; } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -14971,7 +14971,7 @@ root._ = oldDash; } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -14991,7 +14991,7 @@ assert.ok(context.lodash); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -15671,7 +15671,7 @@ assert.deepEqual(actual, expected); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -17166,7 +17166,7 @@ assert.strictEqual(func(array, noop), undefined); } else { - skipTest(assert); + skipAssert(assert); } assert.strictEqual(func(object, noop), undefined); }); @@ -17178,7 +17178,7 @@ assert.strictEqual(_(array)[methodName](add), 6); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -17189,7 +17189,7 @@ assert.ok(_(array).chain()[methodName](add) instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -17260,7 +17260,7 @@ assert.deepEqual(actual.value(), isFilter ? [3, 4] : [1, 2]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -17282,7 +17282,7 @@ assert.deepEqual(actual, _[methodName](lodashStable.mapValues(object, square), predicate)); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -17329,7 +17329,7 @@ assert.deepEqual(args, expected); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }); @@ -17782,7 +17782,7 @@ }); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); @@ -17800,7 +17800,7 @@ }); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -17827,7 +17827,7 @@ assert.deepEqual(array, expected); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -17853,7 +17853,7 @@ }); } else { - skipTest(assert, 8); + skipAssert(assert, 8); } }); @@ -17872,7 +17872,7 @@ }); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -17979,7 +17979,7 @@ assert.ok(pass); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -17999,7 +17999,7 @@ assert.ok(id < oldId); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }()); @@ -18348,7 +18348,7 @@ assert.ok(pass); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -18625,7 +18625,7 @@ }); } else { - skipTest(assert, 38); + skipAssert(assert, 38); } }); }()); @@ -19026,7 +19026,7 @@ assert.strictEqual(actual, expected); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -19087,7 +19087,7 @@ assert.strictEqual(wrapped.split('b').join(','), 'a,c'); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -19309,7 +19309,7 @@ assert.strictEqual(_(1).subtract(2), -1); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -19320,7 +19320,7 @@ assert.ok(_(1).chain().subtract(2) instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -19476,7 +19476,7 @@ assert.deepEqual(values, array); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -19499,7 +19499,7 @@ assert.deepEqual(actual, []); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); }()); @@ -19581,7 +19581,7 @@ assert.deepEqual(actual, _.takeRight(_.take(_.takeRight(_.take(_.filter(_.take(array, array.length - 1), predicate), 6), 4), 2))); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -19663,7 +19663,7 @@ assert.deepEqual(actual, _.take(_.takeRight(_.take(_.takeRight(_.filter(array, predicate), 6), 4), 2))); } else { - skipTest(assert, 6); + skipAssert(assert, 6); } }); }()); @@ -19735,7 +19735,7 @@ assert.strictEqual(wrapped.last(), _.last(expected)); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -19778,7 +19778,7 @@ assert.deepEqual(args, expected); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }()); @@ -19849,7 +19849,7 @@ assert.strictEqual(wrapped.last(), _.last(expected)); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -19868,7 +19868,7 @@ assert.deepEqual(actual, [0]); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -19911,7 +19911,7 @@ assert.deepEqual(args, expected); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }()); @@ -19936,7 +19936,7 @@ assert.strictEqual(intercepted, array); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -19958,7 +19958,7 @@ assert.strictEqual(intercepted, array); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -20684,7 +20684,7 @@ }, 64); } else { - skipTest(assert); + skipAssert(assert); done(); } }); @@ -20973,7 +20973,7 @@ }, 64); } else { - skipTest(assert); + skipAssert(assert); done(); } }); @@ -21112,7 +21112,7 @@ assert.deepEqual(_(3).times(), [0, 1, 2]); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -21123,7 +21123,7 @@ assert.ok(_(3).chain().times() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -21157,7 +21157,7 @@ assert.deepEqual(_.toArray(object), ['a']); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -21178,7 +21178,7 @@ assert.deepEqual(actual, _.map(_.toArray(object).slice(1), String)); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -21260,7 +21260,7 @@ assert.deepEqual(actual, [body]); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -21694,7 +21694,7 @@ } } else { - skipTest(assert); + skipAssert(assert); } }); @@ -21706,7 +21706,7 @@ assert.strictEqual(wrapped.toString(), '1,2,3'); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -22017,7 +22017,7 @@ assert.strictEqual(_(string)[methodName](), expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -22029,7 +22029,7 @@ assert.ok(_(string).chain()[methodName]() instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -22460,7 +22460,7 @@ assert.deepEqual(func(largeArray), largeArray); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -22491,7 +22491,7 @@ assert.deepEqual(func(largeArray), expected); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -22750,7 +22750,7 @@ assert.strictEqual(_.unset(object, 'a'), false); } else { - skipTest(assert); + skipAssert(assert); } }); }()); @@ -23021,7 +23021,7 @@ assert.ok(wrapped instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -23039,7 +23039,7 @@ assert.deepEqual(actual, [1, LARGE_ARRAY_SIZE + 1]); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -23138,7 +23138,7 @@ assert.deepEqual(actual, _.take(_.filter(_.map(func(props, values), square), isEven))); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -23297,7 +23297,7 @@ assert.deepEqual(wrapped.value(), [1, 2, 3, 2, 3]); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -23310,7 +23310,7 @@ assert.strictEqual(wrapped.value(), 1); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -23337,7 +23337,7 @@ assert.deepEqual(wrapped.next(), { 'done': true, 'value': undefined }); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -23352,7 +23352,7 @@ assert.deepEqual(_.toArray(wrapped), array); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -23369,7 +23369,7 @@ }); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); @@ -23388,7 +23388,7 @@ assert.deepEqual(_.toArray(wrapped), [], 'iterator is still exhausted'); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -23408,7 +23408,7 @@ assert.deepEqual(values, array, 'memoizes iterator values'); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }); @@ -23431,7 +23431,7 @@ assert.deepEqual(wrapped1.value(), [1, 9]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); @@ -23447,7 +23447,7 @@ assert.deepEqual(wrapped2.head().value(), 36); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -23466,7 +23466,7 @@ assert.deepEqual(_.toArray(wrapped2), [36, 64]); } else { - skipTest(assert, 3); + skipAssert(assert, 3); } }); }()); @@ -23492,7 +23492,7 @@ assert.strictEqual(actual, array); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }()); @@ -23514,7 +23514,7 @@ assert.deepEqual(actual, [1, 2, 3]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -23540,7 +23540,7 @@ assert.strictEqual(actual, array); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }()); @@ -23562,7 +23562,7 @@ assert.deepEqual(actual, [1, 2, 3]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -23588,7 +23588,7 @@ assert.strictEqual(actual, array); } else { - skipTest(assert, 5); + skipAssert(assert, 5); } }); }()); @@ -23610,7 +23610,7 @@ assert.deepEqual(actual, [1, 2, 3]); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -23633,7 +23633,7 @@ assert.deepEqual(array, [1, 2, 3, 2, 3]); } else { - skipTest(assert, 4); + skipAssert(assert, 4); } }); @@ -23645,7 +23645,7 @@ assert.strictEqual(Number(wrapped), 123); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -23657,7 +23657,7 @@ assert.strictEqual(JSON.stringify(wrapped), '[1,2,3]'); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -23670,7 +23670,7 @@ assert.strictEqual(_.prototype.valueOf, expected); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }()); @@ -23700,7 +23700,7 @@ assert.notStrictEqual(actual, wrapped); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -23738,7 +23738,7 @@ assert.notStrictEqual(actual, wrapped); } else { - skipTest(assert, 2); + skipAssert(assert, 2); } }); }); @@ -23849,7 +23849,7 @@ assert.notOk(actual instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); @@ -23863,7 +23863,7 @@ assert.ok(actual instanceof _); } else { - skipTest(assert); + skipAssert(assert); } }); }); @@ -24116,7 +24116,7 @@ // Skip tests for missing methods of modularized builds. lodashStable.each(['chain', 'noConflict', 'runInContext'], function(methodName) { if (!_[methodName]) { - skipTest(assert); + skipAssert(assert); } }); }); From ee499b36ea0b0a4323eb58ddac5859de50cacdfd Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Fri, 12 Feb 2016 15:20:20 -0500 Subject: [PATCH 50/79] Add _.asArray method. --- lodash.js | 36 ++++++++++++++++++++++++++++++++++++ test/test.js | 43 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/lodash.js b/lodash.js index d54f8ffef9..d5aa8903e7 100644 --- a/lodash.js +++ b/lodash.js @@ -10432,6 +10432,41 @@ return value <= other; } + /** + * Converts a `value` to an array. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example + * + * _.toArray({ 'a': 1, 'b': 2 }); + * // => [{ 'a': 1, 'b': 2 }] + * + * _.toArray([1, 2, 3]); + * // => [1, 2, 3] + * + * _.toArray('abc'); + * // => ['abc'] + * + * _.toArray(1); + * // => [1] + * + * _.toArray(null); + * // => [null] + */ + function asArray(value) { + if (isArray(value)) { + return copyArray(value); + } + if (iteratorSymbol && value && value[iteratorSymbol] && !isString(value)) { + return iteratorToArray(value[iteratorSymbol]()); + } + return [value]; + } + /** * Converts `value` to an array. * @@ -14206,6 +14241,7 @@ // Add functions that return wrapped values when chaining. lodash.after = after; lodash.ary = ary; + lodash.asArray = asArray; lodash.assign = assign; lodash.assignIn = assignIn; lodash.assignInWith = assignInWith; diff --git a/test/test.js b/test/test.js index 9758476cc3..8c49c0a503 100644 --- a/test/test.js +++ b/test/test.js @@ -21185,6 +21185,47 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.asArray'); + + (function() { + var wrapCases = [null, void 0, 1, '', 'ab', 0, {a: 1}, Object('xyz')]; + + QUnit.test('should wrap non array items in an array', function(assert) { + assert.expect(wrapCases.length * 2); + + _.each(wrapCases, function(val) { + var result = _.asArray(val); + assert.deepEqual(result, [val], 'for value ' + val); + assert.strictEqual(result[0], val, 'should not copy the value'); + }); + }); + + QUnit.test('should an array copy if provided array', function(assert) { + assert.expect(2); + + var arr = [1, 2, '3']; + assert.deepEqual(_.asArray(arr), arr); + assert.notStrictEqual(_.asArray(arr), arr); + }); + + QUnit.test('should convert iterables to arrays', function(assert) { + assert.expect(1); + + if (!isNpm && Symbol && Symbol.iterator) { + var object = { '0': 'a', 'length': 1 }; + object[Symbol.iterator] = arrayProto[Symbol.iterator]; + + assert.deepEqual(_.asArray(object), ['a']); + } + else { + skipAssert(assert); + } + }); + + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.toLower'); (function() { @@ -24084,7 +24125,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(296); + assert.expect(297); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray); From 5388d8a7b0823fdccd7b52b313898a3d4142db78 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 12:55:47 -0800 Subject: [PATCH 51/79] Rename `_.asArray` to `_.castArray` and add `_.castFunction` and `_.castPath`. --- lodash.js | 188 +++++++++++++++++++++++++++------------------------ test/test.js | 72 ++++++++------------ 2 files changed, 131 insertions(+), 129 deletions(-) diff --git a/lodash.js b/lodash.js index d5aa8903e7..df22afca8d 100644 --- a/lodash.js +++ b/lodash.js @@ -2203,6 +2203,17 @@ return result; } + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + /** * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. * @@ -2613,7 +2624,7 @@ * @returns {*} Returns the resolved value. */ function baseGet(object, path) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : castPath(path); var index = 0, length = path.length; @@ -2749,7 +2760,7 @@ */ function baseInvoke(object, path, args) { if (!isKey(path, object)) { - path = baseToPath(path); + path = castPath(path); object = parent(object, path); path = last(path); } @@ -3272,7 +3283,7 @@ splice.call(array, index, 1); } else if (!isKey(index, array)) { - var path = baseToPath(index), + var path = castPath(index), object = parent(array, path); if (object != null) { @@ -3334,7 +3345,7 @@ * @returns {Object} Returns `object`. */ function baseSet(object, path, value, customizer) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : castPath(path); var index = -1, length = path.length, @@ -3540,18 +3551,6 @@ return result; } - /** - * The base implementation of `_.toPath` which only converts `value` to a - * path if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the property path array. - */ - function baseToPath(value) { - return isArray(value) ? value : stringToPath(value); - } - /** * The base implementation of `_.uniqBy` without support for iteratee shorthands. * @@ -3621,7 +3620,7 @@ * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ function baseUnset(object, path) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : castPath(path); object = parent(object, path); var key = last(path); return (object != null && has(object, key)) ? delete object[key] : true; @@ -4944,7 +4943,7 @@ } var result = hasFunc(object, path); if (!result && !isKey(path)) { - path = baseToPath(path); + path = castPath(path); object = parent(object, path); if (object != null) { path = last(path); @@ -5325,28 +5324,6 @@ return result; } - /** - * Converts `value` to an array-like object if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the array-like object. - */ - function toArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Converts `value` to a function if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Function} Returns the function. - */ - function toFunction(value) { - return typeof value == 'function' ? value : identity; - } - /** * Creates a clone of `wrapper`. * @@ -5986,7 +5963,7 @@ * // => [2] */ var intersection = rest(function(arrays) { - var mapped = arrayMap(arrays, toArrayLikeObject); + var mapped = arrayMap(arrays, baseCastArrayLikeObject); return (mapped.length && mapped[0] === arrays[0]) ? baseIntersection(mapped) : []; @@ -6014,7 +5991,7 @@ */ var intersectionBy = rest(function(arrays) { var iteratee = last(arrays), - mapped = arrayMap(arrays, toArrayLikeObject); + mapped = arrayMap(arrays, baseCastArrayLikeObject); if (iteratee === last(mapped)) { iteratee = undefined; @@ -6047,7 +6024,7 @@ */ var intersectionWith = rest(function(arrays) { var comparator = last(arrays), - mapped = arrayMap(arrays, toArrayLikeObject); + mapped = arrayMap(arrays, baseCastArrayLikeObject); if (comparator === last(mapped)) { comparator = undefined; @@ -7662,7 +7639,7 @@ function forEach(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEach(collection, iteratee) - : baseEach(collection, toFunction(iteratee)); + : baseEach(collection, castFunction(iteratee)); } /** @@ -7686,7 +7663,7 @@ function forEachRight(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, toFunction(iteratee)); + : baseEachRight(collection, castFunction(iteratee)); } /** @@ -9243,6 +9220,76 @@ /*------------------------------------------------------------------------*/ + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Casts `value` to a function if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Function} Returns the cast function. + */ + function castFunction(value) { + return isFunction(value) ? value : identity; + } + + /** + * Casts `value` to a path if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ + function castPath() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : stringToPath(value); + } + /** * Creates a shallow clone of `value`. * @@ -10432,41 +10479,6 @@ return value <= other; } - /** - * Converts a `value` to an array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [{ 'a': 1, 'b': 2 }] - * - * _.toArray([1, 2, 3]); - * // => [1, 2, 3] - * - * _.toArray('abc'); - * // => ['abc'] - * - * _.toArray(1); - * // => [1] - * - * _.toArray(null); - * // => [null] - */ - function asArray(value) { - if (isArray(value)) { - return copyArray(value); - } - if (iteratorSymbol && value && value[iteratorSymbol] && !isString(value)) { - return iteratorToArray(value[iteratorSymbol]()); - } - return [value]; - } - /** * Converts `value` to an array. * @@ -11036,7 +11048,7 @@ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) */ function forIn(object, iteratee) { - return object == null ? object : baseFor(object, toFunction(iteratee), keysIn); + return object == null ? object : baseFor(object, castFunction(iteratee), keysIn); } /** @@ -11064,7 +11076,7 @@ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' */ function forInRight(object, iteratee) { - return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn); + return object == null ? object : baseForRight(object, castFunction(iteratee), keysIn); } /** @@ -11094,7 +11106,7 @@ * // => logs 'a' then 'b' (iteration order is not guaranteed) */ function forOwn(object, iteratee) { - return object && baseForOwn(object, toFunction(iteratee)); + return object && baseForOwn(object, castFunction(iteratee)); } /** @@ -11122,7 +11134,7 @@ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' */ function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, toFunction(iteratee)); + return object && baseForOwnRight(object, castFunction(iteratee)); } /** @@ -11685,7 +11697,7 @@ */ function result(object, path, defaultValue) { if (!isKey(path, object)) { - path = baseToPath(path); + path = castPath(path); var result = get(object, path); object = parent(object, path); } else { @@ -13854,7 +13866,7 @@ var index = MAX_ARRAY_LENGTH, length = nativeMin(n, MAX_ARRAY_LENGTH); - iteratee = toFunction(iteratee); + iteratee = castFunction(iteratee); n -= MAX_ARRAY_LENGTH; var result = baseTimes(length, iteratee); @@ -14241,7 +14253,6 @@ // Add functions that return wrapped values when chaining. lodash.after = after; lodash.ary = ary; - lodash.asArray = asArray; lodash.assign = assign; lodash.assignIn = assignIn; lodash.assignInWith = assignInWith; @@ -14251,6 +14262,9 @@ lodash.bind = bind; lodash.bindAll = bindAll; lodash.bindKey = bindKey; + lodash.castArray = castArray; + lodash.castFunction = castFunction; + lodash.castPath = castPath; lodash.chain = chain; lodash.chunk = chunk; lodash.compact = compact; diff --git a/test/test.js b/test/test.js index 8c49c0a503..28d1e29f85 100644 --- a/test/test.js +++ b/test/test.js @@ -2158,6 +2158,35 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.castArray'); + + (function() { + QUnit.test('should wrap non array items in an array', function(assert) { + assert.expect(1); + + var values = falsey.concat(true, 1, 'a', { 'a': 1 }), + expected = lodashStable.map(values, function(value) { return [value]; }), + actual = lodashStable.map(values, _.castArray); + + assert.deepEqual(actual, expected); + }); + + QUnit.test('should return array values by reference', function(assert) { + assert.expect(1); + + var array = [1]; + assert.strictEqual(_.castArray(array), array); + }); + + QUnit.test('should return an empty array when no arguments are given', function(assert) { + assert.expect(1); + + assert.deepEqual(_.castArray(), []); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.chain'); (function() { @@ -21185,47 +21214,6 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.asArray'); - - (function() { - var wrapCases = [null, void 0, 1, '', 'ab', 0, {a: 1}, Object('xyz')]; - - QUnit.test('should wrap non array items in an array', function(assert) { - assert.expect(wrapCases.length * 2); - - _.each(wrapCases, function(val) { - var result = _.asArray(val); - assert.deepEqual(result, [val], 'for value ' + val); - assert.strictEqual(result[0], val, 'should not copy the value'); - }); - }); - - QUnit.test('should an array copy if provided array', function(assert) { - assert.expect(2); - - var arr = [1, 2, '3']; - assert.deepEqual(_.asArray(arr), arr); - assert.notStrictEqual(_.asArray(arr), arr); - }); - - QUnit.test('should convert iterables to arrays', function(assert) { - assert.expect(1); - - if (!isNpm && Symbol && Symbol.iterator) { - var object = { '0': 'a', 'length': 1 }; - object[Symbol.iterator] = arrayProto[Symbol.iterator]; - - assert.deepEqual(_.asArray(object), ['a']); - } - else { - skipAssert(assert); - } - }); - - }()); - - /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.toLower'); (function() { @@ -24125,7 +24113,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(297); + assert.expect(299); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray); From a9e8c0ba760ef10781e5ad0e21da8f6aee6ab4cb Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 08:41:43 -0800 Subject: [PATCH 52/79] Add changelog mention to the wiki link in readme. [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a381f3bee..e2c5eb2b81 100644 --- a/README.md +++ b/README.md @@ -51,4 +51,4 @@ Create [custom builds](https://lodash.com/custom-builds) with only the features * [Contributing](https://github.com/lodash/lodash/blob/master/CONTRIBUTING.md) * [Release Notes](https://github.com/lodash/lodash/releases/tag/4.0.0) - * [Wiki](https://github.com/lodash/lodash/wiki) + * [Wiki (Changelog, Roadmap, etc.)](https://github.com/lodash/lodash/wiki) From c5f6c43326c432a4cd917230affefa15b4f7bee7 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 08:57:28 -0800 Subject: [PATCH 53/79] Add default `wrapper` value to jsdoc of `_.wrap`. [ci skip] --- lodash.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lodash.js b/lodash.js index df22afca8d..b41f326afa 100644 --- a/lodash.js +++ b/lodash.js @@ -9202,7 +9202,7 @@ * @memberOf _ * @category Function * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. + * @param {Function} [wrapper=identity] The wrapper function. * @returns {Function} Returns the new function. * @example * From 6e74724c0fe6af3d9845ff17003cc47dd4065a84 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 09:21:07 -0800 Subject: [PATCH 54/79] Add `_.compat` test for lazy sequence with a custom `_.iteratee`. --- test/test.js | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/test/test.js b/test/test.js index 28d1e29f85..3b75a700c6 100644 --- a/test/test.js +++ b/test/test.js @@ -2887,6 +2887,8 @@ QUnit.module('lodash.compact'); (function() { + var largeArray = lodashStable.range(LARGE_ARRAY_SIZE).concat(null); + QUnit.test('should filter falsey values', function(assert) { assert.expect(1); @@ -2913,10 +2915,30 @@ assert.expect(1); if (!isNpm) { - var array = lodashStable.range(LARGE_ARRAY_SIZE).concat(null), - actual = _(array).slice(1).compact().reverse().take().value(); + var actual = _(largeArray).slice(1).compact().reverse().take().value(); + assert.deepEqual(actual, _.take(_.compact(_.slice(largeArray, 1)).reverse())); + } + else { + skipAssert(assert); + } + }); + + QUnit.test('should work in a lazy sequence with a custom `_.iteratee`', function(assert) { + assert.expect(1); - assert.deepEqual(actual, _.take(_.compact(_.slice(array, 1)).reverse())); + if (!isModularize) { + var iteratee = _.iteratee, + pass = false; + + _.iteratee = identity; + + try { + var actual = _(largeArray).slice(1).compact().value(); + pass = lodashStable.isEqual(actual, _.compact(_.slice(largeArray, 1))); + } catch (e) {console.log(e);} + + assert.ok(pass); + _.iteratee = iteratee; } else { skipAssert(assert); From abcebb4f48dbfd8979a3d8cfa6120320205d788a Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 10:07:09 -0800 Subject: [PATCH 55/79] Remove exposed `castFunction` and `castPath`. --- lodash.js | 82 +++++++++++++++++++++++----------------------------- test/test.js | 2 +- 2 files changed, 37 insertions(+), 47 deletions(-) diff --git a/lodash.js b/lodash.js index b41f326afa..8e21e4df15 100644 --- a/lodash.js +++ b/lodash.js @@ -2214,6 +2214,28 @@ return isArrayLikeObject(value) ? value : []; } + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ + function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); + } + /** * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. * @@ -2624,7 +2646,7 @@ * @returns {*} Returns the resolved value. */ function baseGet(object, path) { - path = isKey(path, object) ? [path + ''] : castPath(path); + path = isKey(path, object) ? [path + ''] : baseCastPath(path); var index = 0, length = path.length; @@ -2760,7 +2782,7 @@ */ function baseInvoke(object, path, args) { if (!isKey(path, object)) { - path = castPath(path); + path = baseCastPath(path); object = parent(object, path); path = last(path); } @@ -3283,7 +3305,7 @@ splice.call(array, index, 1); } else if (!isKey(index, array)) { - var path = castPath(index), + var path = baseCastPath(index), object = parent(array, path); if (object != null) { @@ -3345,7 +3367,7 @@ * @returns {Object} Returns `object`. */ function baseSet(object, path, value, customizer) { - path = isKey(path, object) ? [path + ''] : castPath(path); + path = isKey(path, object) ? [path + ''] : baseCastPath(path); var index = -1, length = path.length, @@ -3620,7 +3642,7 @@ * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ function baseUnset(object, path) { - path = isKey(path, object) ? [path + ''] : castPath(path); + path = isKey(path, object) ? [path + ''] : baseCastPath(path); object = parent(object, path); var key = last(path); return (object != null && has(object, key)) ? delete object[key] : true; @@ -4943,7 +4965,7 @@ } var result = hasFunc(object, path); if (!result && !isKey(path)) { - path = castPath(path); + path = baseCastPath(path); object = parent(object, path); if (object != null) { path = last(path); @@ -7639,7 +7661,7 @@ function forEach(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEach(collection, iteratee) - : baseEach(collection, castFunction(iteratee)); + : baseEach(collection, baseCastFunction(iteratee)); } /** @@ -7663,7 +7685,7 @@ function forEachRight(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, castFunction(iteratee)); + : baseEachRight(collection, baseCastFunction(iteratee)); } /** @@ -9260,36 +9282,6 @@ return isArray(value) ? value : [value]; } - /** - * Casts `value` to a function if it's not one. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to inspect. - * @returns {Function} Returns the cast function. - */ - function castFunction(value) { - return isFunction(value) ? value : identity; - } - - /** - * Casts `value` to a path if it's not one. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast property path array. - */ - function castPath() { - if (!arguments.length) { - return []; - } - var value = arguments[0]; - return isArray(value) ? value : stringToPath(value); - } - /** * Creates a shallow clone of `value`. * @@ -11048,7 +11040,7 @@ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) */ function forIn(object, iteratee) { - return object == null ? object : baseFor(object, castFunction(iteratee), keysIn); + return object == null ? object : baseFor(object, baseCastFunction(iteratee), keysIn); } /** @@ -11076,7 +11068,7 @@ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' */ function forInRight(object, iteratee) { - return object == null ? object : baseForRight(object, castFunction(iteratee), keysIn); + return object == null ? object : baseForRight(object, baseCastFunction(iteratee), keysIn); } /** @@ -11106,7 +11098,7 @@ * // => logs 'a' then 'b' (iteration order is not guaranteed) */ function forOwn(object, iteratee) { - return object && baseForOwn(object, castFunction(iteratee)); + return object && baseForOwn(object, baseCastFunction(iteratee)); } /** @@ -11134,7 +11126,7 @@ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' */ function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, castFunction(iteratee)); + return object && baseForOwnRight(object, baseCastFunction(iteratee)); } /** @@ -11697,7 +11689,7 @@ */ function result(object, path, defaultValue) { if (!isKey(path, object)) { - path = castPath(path); + path = baseCastPath(path); var result = get(object, path); object = parent(object, path); } else { @@ -13866,7 +13858,7 @@ var index = MAX_ARRAY_LENGTH, length = nativeMin(n, MAX_ARRAY_LENGTH); - iteratee = castFunction(iteratee); + iteratee = baseCastFunction(iteratee); n -= MAX_ARRAY_LENGTH; var result = baseTimes(length, iteratee); @@ -14263,8 +14255,6 @@ lodash.bindAll = bindAll; lodash.bindKey = bindKey; lodash.castArray = castArray; - lodash.castFunction = castFunction; - lodash.castPath = castPath; lodash.chain = chain; lodash.chunk = chunk; lodash.compact = compact; diff --git a/test/test.js b/test/test.js index 3b75a700c6..9111a91ad7 100644 --- a/test/test.js +++ b/test/test.js @@ -24135,7 +24135,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(299); + assert.expect(297); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray); From d358d00531154c34d15c3ae020279b61d3f62d6d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 11:38:33 -0800 Subject: [PATCH 56/79] Ensure fp `castArray` shallow clones arrays. --- fp/_baseConvert.js | 10 ++++++++++ fp/_mapping.js | 6 +++--- test/test-fp.js | 47 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index cb8975b2b8..ba5abe706c 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -47,6 +47,7 @@ function baseConvert(util, name, func, options) { 'cloneDeep': util.cloneDeep, 'curry': util.curry, 'forEach': util.forEach, + 'isArray': util.isArray, 'isFunction': util.isFunction, 'iteratee': util.iteratee, 'keys': util.keys, @@ -58,6 +59,7 @@ function baseConvert(util, name, func, options) { cloneDeep = helpers.cloneDeep, curry = helpers.curry, each = helpers.forEach, + isArray = helpers.isArray, isFunction = helpers.isFunction, keys = helpers.keys, rearg = helpers.rearg, @@ -130,6 +132,14 @@ function baseConvert(util, name, func, options) { }; var wrappers = { + 'castArray': function(castArray) { + return function() { + var value = arguments[0]; + return isArray(value) + ? castArray(cloneArray(value)) + : castArray.apply(undefined, arguments); + }; + }, 'iteratee': function(iteratee) { return function() { var func = arguments[0], diff --git a/fp/_mapping.js b/fp/_mapping.js index 57fbf28e5f..5e817b04a0 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -39,9 +39,9 @@ exports.aliasToReal = { /** Used to map ary to method names. */ exports.aryMethod = { 1: [ - 'attempt', 'ceil', 'create', 'curry', 'curryRight', 'floor', 'fromPairs', - 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', 'over', - 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', + 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', + 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', + 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' ], 2: [ diff --git a/test/test-fp.js b/test/test-fp.js index 9a29fc8661..d09e4e5be6 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -773,6 +773,48 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('fp.castArray'); + + (function() { + QUnit.test('should shallow clone array values', function(assert) { + assert.expect(2); + + var array = [1], + actual = fp.castArray(array); + + assert.deepEqual(actual, array); + assert.notStrictEqual(actual, array); + }); + + QUnit.test('should not shallow clone non-array values', function(assert) { + assert.expect(2); + + var object = { 'a': 1 }, + actual = fp.castArray(object); + + assert.deepEqual(actual, [object]); + assert.strictEqual(actual[0], object); + }); + + QUnit.test('should convert by name', function(assert) { + assert.expect(4); + + var array = [1], + object = { 'a': 1 }, + castArray = convert('castArray', _.castArray), + actual = castArray(array); + + assert.deepEqual(actual, array); + assert.notStrictEqual(actual, array); + + actual = castArray(object); + assert.deepEqual(actual, [object]); + assert.strictEqual(actual[0], object); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('fp.curry and fp.curryRight'); _.each(['curry', 'curryRight'], function(methodName) { @@ -823,9 +865,8 @@ function Foo() {} Foo.prototype = { 'b': 2 }; - var object = { 'a': 1 }; - - var extend = convert('extend', _.extend), + var object = { 'a': 1 }, + extend = convert('extend', _.extend), value = _.clone(object), actual = extend(value)(new Foo); From c006c28f553b9f9c548f994e0c225a8a2e85e111 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 12:57:34 -0800 Subject: [PATCH 57/79] Add lib/common/util. --- lib/common/util.js | 18 ++++++++++++++++ lib/fp/build-modules.js | 47 +++++++++++++++++++++++------------------ 2 files changed, 45 insertions(+), 20 deletions(-) create mode 100644 lib/common/util.js diff --git a/lib/common/util.js b/lib/common/util.js new file mode 100644 index 0000000000..056b760d5b --- /dev/null +++ b/lib/common/util.js @@ -0,0 +1,18 @@ +'use strict'; + +var _ = require('lodash'), + fs = require('fs-extra'), + glob = require('glob'), + path = require('path'); + +/*----------------------------------------------------------------------------*/ + +function globTemplate(pattern) { + return _.transform(glob.sync(pattern), function(result, filePath) { + result[path.basename(filePath, path.extname(filePath))] = _.template(fs.readFileSync(filePath)); + }, {}); +} + +module.exports = { + 'globTemplate': globTemplate +}; diff --git a/lib/fp/build-modules.js b/lib/fp/build-modules.js index 4462647dab..bc268f88da 100644 --- a/lib/fp/build-modules.js +++ b/lib/fp/build-modules.js @@ -4,15 +4,12 @@ var _ = require('lodash'), async = require('async'), fs = require('fs-extra'), glob = require('glob'), - path = require('path'); + path = require('path'), + util = require('../common/util'); -var mapping = require('../../fp/_mapping'); - -var templatePath = path.join(__dirname, 'template/modules'); - -var template = _.transform(glob.sync(path.join(templatePath, '*.jst')), function(result, filePath) { - result[path.basename(filePath, '.jst')] = _.template(fs.readFileSync(filePath)); -}, {}); +var mapping = require('../../fp/_mapping'), + templatePath = path.join(__dirname, 'template/modules'), + template = util.globTemplate(path.join(templatePath, '*.jst')); var aryMethods = _.union( mapping.aryMethod[1], @@ -35,6 +32,18 @@ var categories = [ 'util' ]; +var ignored = [ + '_*.js', + 'core.js', + 'fp.js', + 'index.js', + 'lodash.js' +]; + +function copyFile(srcPath, destPath) { + return _.partial(fs.copy, srcPath, destPath); +} + function isAlias(funcName) { return _.has(mapping.aliasToReal, funcName); } @@ -65,6 +74,10 @@ function getTemplate(moduleName) { return template.module(data); } +function writeFile(filePath, data) { + return _.partial(fs.writeFile, filePath, data); +} + /*----------------------------------------------------------------------------*/ function onComplete(error) { @@ -79,13 +92,7 @@ function build(target) { // Glob existing lodash module paths. var modulePaths = glob.sync(path.join(target, '*.js'), { 'nodir': true, - 'ignore': [ - '_*.js', - 'core.js', - 'fp.js', - 'index.js', - 'lodash.js' - ].map(function(filename) { + 'ignore': ignored.map(function(filename) { return path.join(target, filename); }) }); @@ -103,13 +110,13 @@ function build(target) { var actions = modulePaths.map(function(modulePath) { var moduleName = path.basename(modulePath, '.js'); - return _.partial(fs.writeFile, path.join(fpPath, moduleName + '.js'), getTemplate(moduleName)); + return writeFile(path.join(fpPath, moduleName + '.js'), getTemplate(moduleName)); }); - actions.unshift(_.partial(fs.copy, path.join(__dirname, '../../fp'), fpPath)); - actions.push(_.partial(fs.writeFile, path.join(target, 'fp.js'), template.fp())); - actions.push(_.partial(fs.writeFile, path.join(fpPath, 'convert.js'), template.convert())); - actions.push(_.partial(fs.writeFile, path.join(fpPath, '_util.js'), template._util())); + actions.unshift(copyFile(path.join(__dirname, '../../fp'), fpPath)); + actions.push(writeFile(path.join(target, 'fp.js'), template.fp())); + actions.push(writeFile(path.join(fpPath, 'convert.js'), template.convert())); + actions.push(writeFile(path.join(fpPath, '_util.js'), template._util())); async.series(actions, onComplete); } From cb96bf15b7f2c07c393bd089206a345db9ad0464 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 19:14:17 -0800 Subject: [PATCH 58/79] Reduce the length of some lines. --- lodash.js | 192 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 143 insertions(+), 49 deletions(-) diff --git a/lodash.js b/lodash.js index 8e21e4df15..cc2ffb6d07 100644 --- a/lodash.js +++ b/lodash.js @@ -334,10 +334,19 @@ freeParseInt = parseInt; /** Detect free variable `exports`. */ - var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null; + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; /** Detect free variable `module`. */ - var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null; + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; /** Detect free variable `global` from Node.js. */ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); @@ -348,9 +357,6 @@ /** Detect free variable `window`. */ var freeWindow = checkGlobal(objectTypes[typeof window] && window); - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null; - /** Detect `this` as the global object. */ var thisGlobal = checkGlobal(objectTypes[typeof this] && this); @@ -360,7 +366,9 @@ * The `this` value is used if it's the global object to avoid Greasemonkey's * restricted `window` object, otherwise the `window` object is used. */ - var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')(); + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); /*--------------------------------------------------------------------------*/ @@ -1645,7 +1653,8 @@ resIndex = 0, takeCount = nativeMin(length, this.__takeCount__); - if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { return baseWrapperValue(array, this.__actions__); } var result = []; @@ -1769,7 +1778,11 @@ * @memberOf MapCache */ function mapClear() { - this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash }; + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; } /** @@ -2735,11 +2748,17 @@ var value = array[index], computed = iteratee ? iteratee(value) : value; - if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) { + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { var othIndex = othLength; while (--othIndex) { var cache = caches[othIndex]; - if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) { + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { continue outer; } } @@ -3062,7 +3081,10 @@ if (object === source) { return; } - var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source); + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); + arrayEach(props || source, function(srcValue, key) { if (props) { key = srcValue; @@ -3073,7 +3095,10 @@ baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); } else { - var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined; + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + if (newValue === undefined) { newValue = srcValue; } @@ -3105,8 +3130,11 @@ assignMergeValue(object, key, stacked); return; } - var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined, - isCommon = newValue === undefined; + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; if (isCommon) { newValue = srcValue; @@ -3382,7 +3410,9 @@ var objValue = nested[key]; newValue = customizer ? customizer(objValue, key, nested) : undefined; if (newValue === undefined) { - newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue; + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; } } assignValue(nested, key, newValue); @@ -3831,10 +3861,11 @@ * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { - var buffer = typedArray.buffer, + var arrayBuffer = typedArray.buffer, + buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer, Ctor = typedArray.constructor; - return new Ctor(isDeep ? cloneArrayBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length); + return new Ctor(buffer, typedArray.byteOffset, typedArray.length); } /** @@ -3949,8 +3980,11 @@ length = props.length; while (++index < length) { - var key = props[index], - newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key]; + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; assignValue(object, key, newValue); } @@ -4000,7 +4034,10 @@ customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; - customizer = typeof customizer == 'function' ? (length--, customizer) : undefined; + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; @@ -4101,8 +4138,11 @@ return function(string) { string = toString(string); - var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined, - chr = strSymbols ? strSymbols[0] : string.charAt(0), + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); return chr[methodName]() + trailing; @@ -4223,7 +4263,10 @@ var funcName = getFuncName(func), data = funcName == 'wrapper' ? getData(func) : undefined; - if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); } else { wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); @@ -4233,7 +4276,8 @@ var args = arguments, value = args[0]; - if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { return wrapper.plant(value).value(); } var index = 0, @@ -4293,7 +4337,10 @@ length -= argsHolders.length; if (length < arity) { - return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, placeholder, thisArg, args, + argsHolders, argPos, ary, arity - length + ); } } var thisBinding = isBind ? thisArg : this, @@ -4465,9 +4512,12 @@ if (!(bitmask & CURRY_BOUND_FLAG)) { bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); } - var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity], - result = wrapFunc.apply(undefined, newData); + var newData = [ + func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + var result = wrapFunc.apply(undefined, newData); if (isLaziable(func)) { setData(result, newData); } @@ -4556,8 +4606,12 @@ partials = holders = undefined; } - var data = isBindKey ? undefined : getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; if (data) { mergeData(newData, data); @@ -7193,11 +7247,16 @@ value = this.__wrapped__, interceptor = function(object) { return baseAt(object, paths); }; - if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) { + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { return this.thru(interceptor); } value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); return new LodashWrapper(value, this.__chain__).thru(function(array) { if (length && !array.length) { array.push(undefined); @@ -7408,7 +7467,11 @@ wrapped = new LazyWrapper(this); } wrapped = wrapped.reverse(); - wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined }); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); return new LodashWrapper(wrapped, this.__chain__); } return this.thru(reverse); @@ -8686,8 +8749,10 @@ if (!lastCalled && !maxTimeoutId && !leading) { lastCalled = stamp; } - var remaining = maxWait - (stamp - lastCalled), - isCalled = (remaining <= 0 || remaining > maxWait) && (leading || maxTimeoutId); + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); if (isCalled) { if (maxTimeoutId) { @@ -9193,7 +9258,11 @@ leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } - return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing }); + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); } /** @@ -9708,7 +9777,8 @@ */ function isEmpty(value) { if (isArrayLike(value) && - (isArray(value) || isString(value) || isFunction(value.splice) || isArguments(value))) { + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { return !value.length; } for (var key in value) { @@ -9918,7 +9988,8 @@ * // => false */ function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** @@ -10217,7 +10288,8 @@ * // => true */ function isPlainObject(value) { - if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { return false; } var proto = objectProto; @@ -10360,7 +10432,8 @@ * // => false */ function isTypedArray(value) { - return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; } /** @@ -11040,7 +11113,9 @@ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) */ function forIn(object, iteratee) { - return object == null ? object : baseFor(object, baseCastFunction(iteratee), keysIn); + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); } /** @@ -11068,7 +11143,9 @@ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' */ function forInRight(object, iteratee) { - return object == null ? object : baseForRight(object, baseCastFunction(iteratee), keysIn); + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); } /** @@ -12810,7 +12887,8 @@ 'return __p\n}'; var result = attempt(function() { - return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues); + return Function(importsKeys, sourceURL + 'return ' + source) + .apply(undefined, importsValues); }); // Provide the compiled function's source by its `toString` method or @@ -12904,7 +12982,9 @@ var strSymbols = stringToArray(string), chrSymbols = stringToArray(chars); - return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join(''); + return strSymbols + .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1) + .join(''); } /** @@ -12938,7 +13018,9 @@ return string; } var strSymbols = stringToArray(string); - return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join(''); + return strSymbols + .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1) + .join(''); } /** @@ -12972,7 +13054,9 @@ return string; } var strSymbols = stringToArray(string); - return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join(''); + return strSymbols + .slice(charsStartIndex(strSymbols, stringToArray(chars))) + .join(''); } /** @@ -13368,7 +13452,8 @@ * Creates a function that invokes `func` with the arguments of the created * function. If `func` is a property name the created callback returns the * property value for a given element. If `func` is an object the created - * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`. + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. * * @static * @memberOf _ @@ -14580,7 +14665,10 @@ if (filtered) { result.__takeCount__ = nativeMin(n, result.__takeCount__); } else { - result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); + result.__views__.push({ + 'size': nativeMin(n, MAX_ARRAY_LENGTH), + 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') + }); } return result; }; @@ -14597,7 +14685,10 @@ LazyWrapper.prototype[methodName] = function(iteratee) { var result = this.clone(); - result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type }); + result.__iteratees__.push({ + 'iteratee': getIteratee(iteratee, 3), + 'type': type + }); result.__filtered__ = result.__filtered__ || isFilter; return result; }; @@ -14749,7 +14840,10 @@ } }); - realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; + realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ + 'name': 'wrapper', + 'func': undefined + }]; // Add functions to the lazy wrapper. LazyWrapper.prototype.clone = lazyClone; From aae02af2650d197fff15519a438f16ae994bb449 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 19:20:17 -0800 Subject: [PATCH 59/79] Cleanup `Date` shims. --- test/test.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test/test.js b/test/test.js index 9111a91ad7..4b79aa5260 100644 --- a/test/test.js +++ b/test/test.js @@ -8860,9 +8860,11 @@ QUnit.test('should compare date objects', function(assert) { assert.expect(4); - assert.strictEqual(_.isEqual(new Date(2012, 4, 23), new Date(2012, 4, 23)), true); - assert.strictEqual(_.isEqual(new Date(2012, 4, 23), new Date(2013, 3, 25)), false); - assert.strictEqual(_.isEqual(new Date(2012, 4, 23), { 'getTime': lodashStable.constant(1337756400000) }), false); + var date = new Date(2012, 4, 23); + + assert.strictEqual(_.isEqual(date, new Date(2012, 4, 23)), true); + assert.strictEqual(_.isEqual(date, new Date(2013, 3, 25)), false); + assert.strictEqual(_.isEqual(date, { 'getTime': lodashStable.constant(+date) }), false); assert.strictEqual(_.isEqual(new Date('a'), new Date('a')), false); }); @@ -20710,7 +20712,9 @@ dateCount = 0; var getTime = function() { - return ++dateCount == 5 ? Infinity : +new Date; + return ++dateCount == 5 + ? Infinity + : +new Date; }; var lodash = _.runInContext(lodashStable.assign({}, root, { @@ -21000,7 +21004,9 @@ dateCount = 0; var getTime = function() { - return ++dateCount === 4 ? +new Date(2012, 3, 23, 23, 27, 18) : +new Date; + return ++dateCount === 4 + ? +new Date(2012, 3, 23, 23, 27, 18) + : +new Date; }; var lodash = _.runInContext(lodashStable.assign({}, root, { From c163659713f4497e1dcb56ed621934c39652230d Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 23:47:03 -0800 Subject: [PATCH 60/79] Rename fp mapping `rename` to `remap`. --- fp/_baseConvert.js | 2 +- fp/_mapping.js | 2 +- lib/fp/build-modules.js | 4 ++-- lib/fp/template/modules/module.jst | 2 +- test/test-fp.js | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index ba5abe706c..9eaa8212f9 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -254,7 +254,7 @@ function baseConvert(util, name, func, options) { var pairs = []; each(mapping.caps, function(cap) { each(mapping.aryMethod[cap], function(key) { - var func = _[mapping.rename[key] || key]; + var func = _[mapping.remap[key] || key]; if (func) { pairs.push([key, wrap(key, func)]); } diff --git a/fp/_mapping.js b/fp/_mapping.js index 5e817b04a0..4726799a11 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -203,7 +203,7 @@ exports.realToAlias = (function() { }()); /** Used to map method names to other names. */ -exports.rename = { +exports.remap = { 'curryN': 'curry', 'curryRightN': 'curryRight', 'getOr': 'get', diff --git a/lib/fp/build-modules.js b/lib/fp/build-modules.js index bc268f88da..36a8a741f6 100644 --- a/lib/fp/build-modules.js +++ b/lib/fp/build-modules.js @@ -59,7 +59,7 @@ function isThru(funcName) { function getTemplate(moduleName) { var data = { 'name': _.result(mapping.aliasToReal, moduleName, moduleName), - 'rename': mapping.rename + 'mapping': mapping }; if (isAlias(moduleName)) { @@ -98,7 +98,7 @@ function build(target) { }); // Add FP alias and remapped module paths. - _.each([mapping.aliasToReal, mapping.rename], function(data) { + _.each([mapping.aliasToReal, mapping.remap], function(data) { _.forOwn(data, function(realName, alias) { if (!_.startsWith(alias, '_')) { modulePaths.push(path.join(target, alias + '.js')); diff --git a/lib/fp/template/modules/module.jst b/lib/fp/template/modules/module.jst index da044af5a8..a1ff9f6620 100644 --- a/lib/fp/template/modules/module.jst +++ b/lib/fp/template/modules/module.jst @@ -1,2 +1,2 @@ var convert = require('./convert'); -module.exports = convert('<%= name %>', require('../<%= _.result(rename, name, name) %>')); +module.exports = convert('<%= name %>', require('../<%= _.result(mapping.remap, name, name) %>')); diff --git a/test/test-fp.js b/test/test-fp.js index d09e4e5be6..12378a77d0 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -291,7 +291,7 @@ var aryCap = index + 1; var methodNames = _.filter(mapping.aryMethod[aryCap], function(methodName) { - var key = _.result(mapping.rename, methodName, methodName), + var key = _.result(mapping.remap, methodName, methodName), arity = _[key].length; return arity != 0 && arity < aryCap; From 19613be86100295984192d5180ce989cd962b7d3 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 23:47:22 -0800 Subject: [PATCH 61/79] Add `isArray` to _util.jst. --- lib/fp/template/modules/_util.jst | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/fp/template/modules/_util.jst b/lib/fp/template/modules/_util.jst index e1baf3b0a0..6f776a9e9f 100644 --- a/lib/fp/template/modules/_util.jst +++ b/lib/fp/template/modules/_util.jst @@ -3,6 +3,7 @@ module.exports = { 'cloneDeep': require('../cloneDeep'), 'curry': require('../curry'), 'forEach': require('../_arrayEach'), + 'isArray': require('../isArray'), 'isFunction': require('../isFunction'), 'iteratee': require('../iteratee'), 'keys': require('../_baseKeys'), From cf1a4f893ff3e72a2fb4cab48a613377beb467b6 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 14 Feb 2016 20:04:35 -0800 Subject: [PATCH 62/79] Update fp doc generation. --- lib/fp/build-doc.js | 40 ++++++++++++++++++++-- lib/fp/template/doc/wiki.jst | 64 ++++++++++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/lib/fp/build-doc.js b/lib/fp/build-doc.js index 0e9bd604a0..b67c881326 100644 --- a/lib/fp/build-doc.js +++ b/lib/fp/build-doc.js @@ -1,9 +1,45 @@ 'use strict'; +var _ = require('lodash'), + fs = require('fs-extra'), + path = require('path'), + util = require('../common/util'); + +var basePath = path.join(__dirname, '..', '..'), + docPath = path.join(basePath, 'doc'), + readmePath = path.join(docPath, 'FP-Guide.md'); + +var mapping = require('../../fp/_mapping'), + templatePath = path.join(__dirname, 'template/doc'), + template = util.globTemplate(path.join(templatePath, '*.jst')); + +var templateData = { + 'mapping': mapping, + 'toFuncList': toFuncList +}; + +function toFuncList(array) { + var chunks = _.chunk(array.slice().sort(), 5), + lastChunk = _.last(chunks), + last = lastChunk ? lastChunk.pop() : undefined; + + var result = '`' + _.map(chunks, function(chunk) { + return chunk.join('`, `') + '`'; + }).join(',\n`'); + + return result + (last == null ? '' : (', & `' + last + '`')); +} + /*----------------------------------------------------------------------------*/ -function build(type) { +function onComplete(error) { + if (error) { + throw error; + } +} +function build() { + fs.writeFile(readmePath, template.wiki(templateData), onComplete); } -build(_.last(process.argv)); +build(); diff --git a/lib/fp/template/doc/wiki.jst b/lib/fp/template/doc/wiki.jst index 8b13789179..6cc54e554d 100644 --- a/lib/fp/template/doc/wiki.jst +++ b/lib/fp/template/doc/wiki.jst @@ -1 +1,65 @@ +## lodash/fp +The lodash/fp module is an instance of lodash with its methods wrapped to produce +immutable auto-curried iteratee-first data-last methods. + +## Installation + +In a browser: +```html + + +``` + +In Node.js: +```js +// load the fp build +var _ = require('lodash/fp'); + +// or a method category +var array = require('lodash/fp/object'); + +// or method for smaller builds with browserify/rollup/webpack +var extend = require('lodash/fp/extend'); +``` + +## Notes + +#### Arity + +Methods with arity capped to one argument:
+<%= toFuncList(mapping.aryMethod[1]) %> + +Methods with arity capped to two arguments:
+<%= toFuncList(mapping.aryMethod[2]) %> + +Methods with arity capped to three arguments:
+<%= toFuncList(mapping.aryMethod[3]) %> + +Methods with arity capped to four arguments:
+<%= toFuncList(mapping.aryMethod[4]) %> + +#### Iteratees + +Methods which provide iteratees one argument:
+<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 1)))) %> + +Methods which provide iteratees two argument:
+<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 2)))) %> + +#### New Methods + +Methods created to accommodate Lodash’s variadic methods:
+<%= toFuncList(_.keys(mapping.remap)) %> + +#### Exceptions + +Methods which have argument order unchanged:
+<%= toFuncList(_.keys(mapping.skipRearg)) %> + +#### Aliases + +There are <%= _.size(mapping.aliasToReal) %> method aliases:
+<%= _.map(mapping.aliasToReal, function(realName, alias) { + return ' - Added `_.' + alias + '` as an alias of `_.' + realName + '`'; +}).join('\n') %> diff --git a/package.json b/package.json index 3635e3394c..e9cba669d1 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "build:main": "node lib/main/build-dist.js", "build:main-modules": "node lib/main/build-modules.js", "doc": "node lib/main/build-doc github", + "doc:fp": "node lib/fp/build-doc", "doc:site": "node lib/main/build-doc site", "prepublish": "npm run style", "pretest": "npm run build", From 761a100397253989918f2033641c8331fb0ba1c9 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 09:14:10 -0800 Subject: [PATCH 63/79] Ensure `_.valuesIn` returns results. [closes #2000] --- lodash.js | 2 +- test/test.js | 36 +++++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lodash.js b/lodash.js index cc2ffb6d07..b7b1e1dc74 100644 --- a/lodash.js +++ b/lodash.js @@ -12017,7 +12017,7 @@ * // => [1, 2, 3] (iteration order is not guaranteed) */ function valuesIn(object) { - return object == null ? baseValues(object, keysIn(object)) : []; + return object == null ? [] : baseValues(object, keysIn(object)); } /*------------------------------------------------------------------------*/ diff --git a/test/test.js b/test/test.js index 4b79aa5260..6542d6fd36 100644 --- a/test/test.js +++ b/test/test.js @@ -12024,7 +12024,7 @@ assert.deepEqual(func(array).sort(), ['0', 'a']); }); - QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties of arrays', function(assert) { + QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties of arrays', function(assert) { assert.expect(1); var expected = isKeys ? ['0'] : ['0', 'a']; @@ -12060,7 +12060,7 @@ assert.deepEqual(actual, expected); }); - QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties of `arguments` objects', function(assert) { + QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties of `arguments` objects', function(assert) { assert.expect(1); var values = [args, strictArgs], @@ -12091,7 +12091,7 @@ assert.deepEqual(func(object).sort(), ['0', 'a']); }); - QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties of string objects', function(assert) { + QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties of string objects', function(assert) { assert.expect(1); var expected = isKeys ? ['0'] : ['0', 'a']; @@ -12118,7 +12118,7 @@ assert.deepEqual(func(Fake.prototype), ['constructor']); }); - QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not' : '') + ' include inherited properties', function(assert) { + QUnit.test('`_.' + methodName + '` should ' + (isKeys ? 'not ' : '') + 'include inherited properties', function(assert) { assert.expect(1); function Foo() { this.a = 1; } @@ -22858,23 +22858,37 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.values'); + QUnit.module('values methods'); - (function() { - QUnit.test('should get the values of an object', function(assert) { + lodashStable.each(['values', 'valuesIn'], function(methodName) { + var args = (function() { return arguments; }(1, 2, 3)), + func = _[methodName], + isValues = methodName == 'values'; + + QUnit.test('`_.' + methodName + '` should get the values of an object', function(assert) { assert.expect(1); var object = { 'a': 1, 'b': 2 }; - assert.deepEqual(_.values(object), [1, 2]); + assert.deepEqual(func(object), [1, 2]); }); - QUnit.test('should work with an object that has a `length` property', function(assert) { + QUnit.test('`_.' + methodName + '` should work with an object that has a `length` property', function(assert) { assert.expect(1); var object = { '0': 'a', '1': 'b', 'length': 2 }; - assert.deepEqual(_.values(object), ['a', 'b', 2]); + assert.deepEqual(func(object), ['a', 'b', 2]); }); - }()); + + QUnit.test('`_.' + methodName + '` should ' + (isValues ? 'not ' : '') + ' include inherited property values', function(assert) { + assert.expect(1); + + function Foo() { this.a = 1; } + Foo.prototype.b = 2; + + var expected = isValues ? [1] : [1, 2]; + assert.deepEqual(func(new Foo).sort(), expected); + }); + }); /*--------------------------------------------------------------------------*/ From 641b544801501ddfde4d73c87e7ec4a1b199fc0e Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 10:20:40 -0800 Subject: [PATCH 64/79] Add `castArray` to lodash chaining doc note. [ci skip] --- lodash.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lodash.js b/lodash.js index b7b1e1dc74..4b274c84fc 100644 --- a/lodash.js +++ b/lodash.js @@ -1402,10 +1402,10 @@ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, - * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`, - * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`, - * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, From 6e399ce311878d5d335666bcdb5729cab7b4ca38 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 10:21:19 -0800 Subject: [PATCH 65/79] Cleanup long lines in `isEqualWith` docs. [ci skip] --- lodash.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lodash.js b/lodash.js index 4b274c84fc..f0a5220b1c 100644 --- a/lodash.js +++ b/lodash.js @@ -9821,10 +9821,10 @@ } /** - * This method is like `_.isEqual` except that it accepts `customizer` which is - * invoked to compare values. If `customizer` returns `undefined` comparisons are - * handled by the method instead. The `customizer` is invoked with up to six arguments: - * (objValue, othValue [, index|key, object, other, stack]). + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). * * @static * @memberOf _ From dc2fc9428d0b47c0327c4b4fff1894b89472eea1 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 10:22:04 -0800 Subject: [PATCH 66/79] Cross reference `_.matches` and `_.isMatch` in docs. [ci skip] --- lodash.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lodash.js b/lodash.js index f0a5220b1c..a28d15a615 100644 --- a/lodash.js +++ b/lodash.js @@ -10068,8 +10068,9 @@ } /** - * Performs a deep comparison between `object` and `source` to determine if - * `object` contains equivalent property values. + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. * * **Note:** This method supports comparing the same values as `_.isEqual`. * @@ -13483,9 +13484,10 @@ } /** - * Creates a function that performs a deep partial comparison between a given + * Creates a function that performs a partial deep comparison between a given * object and `source`, returning `true` if the given object has equivalent - * property values, else `false`. + * property values, else `false`. The created function is equivalent to + * `_.isMatch` with a `source` partially applied. * * **Note:** This method supports comparing the same values as `_.isEqual`. * @@ -13509,7 +13511,7 @@ } /** - * Creates a function that performs a deep partial comparison between the + * Creates a function that performs a partial deep comparison between the * value at `path` of a given object to `srcValue`, returning `true` if the * object value is equivalent, else `false`. * From 3846348f8a4682559a61c232eb5946078cc27a48 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 10:22:25 -0800 Subject: [PATCH 67/79] Clarify how `undefined` source values are handled in `_.merge`. [ci skip] --- lodash.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lodash.js b/lodash.js index a28d15a615..3e82ce668a 100644 --- a/lodash.js +++ b/lodash.js @@ -11571,12 +11571,12 @@ } /** - * Recursively merges own and inherited enumerable properties of source - * objects into the destination object, skipping source properties that resolve - * to `undefined`. Array and plain object properties are merged recursively. - * Other objects and value types are overridden by assignment. Source objects - * are applied from left to right. Subsequent sources overwrite property - * assignments of previous sources. + * Recursively merges own and inherited enumerable properties of source objects + * into the destination object. Source properties that resolve to `undefined` + * are skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object`. * From 04180c7c961d7aaba4584591bee863455e93ee68 Mon Sep 17 00:00:00 2001 From: greenkeeperio-bot Date: Mon, 15 Feb 2016 10:52:22 -0800 Subject: [PATCH 68/79] Update jscs to 2.10.1. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9cba669d1..5e6546e940 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "glob": "^7.0.0", "istanbul": "0.4.2", "jquery": "^2.2.0", - "jscs": "^2.9.0", + "jscs": "^2.10.1", "lodash": "^3.10.1", "platform": "^1.3.1", "qunit-extras": "^1.4.5", From 4643679d79ea7244c40fd469cce9fab0ffa6878c Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 13:50:39 -0800 Subject: [PATCH 69/79] Remove fp `caps` mapping. --- fp/_baseConvert.js | 20 ++++++----- fp/_mapping.js | 83 ++++++++++++++++++++++------------------------ 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index 9eaa8212f9..d0504cacc1 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -65,6 +65,8 @@ function baseConvert(util, name, func, options) { rearg = helpers.rearg, spread = helpers.spread; + var aryMethodKeys = keys(mapping.aryMethod); + var baseArity = function(func, n) { return n == 2 ? function(a, b) { return func.apply(undefined, arguments); } @@ -210,8 +212,8 @@ function baseConvert(util, name, func, options) { } } var result; - each(mapping.caps, function(cap) { - each(mapping.aryMethod[cap], function(otherName) { + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(otherName) { if (name == otherName) { var aryN = !isLib && mapping.iterateeAry[name], spreadStart = mapping.methodSpread[name]; @@ -219,17 +221,17 @@ function baseConvert(util, name, func, options) { result = wrapped; if (config.fixed) { result = spreadStart === undefined - ? ary(result, cap) + ? ary(result, aryKey) : spread(result, spreadStart); } - if (config.rearg && cap > 1 && (forceRearg || !mapping.skipRearg[name])) { - result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]); + if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) { + result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]); } if (config.cap && aryN) { result = iterateeAry(result, aryN); } - if (config.curry && cap > 1) { - result = curry(result, cap); + if (config.curry && aryKey > 1) { + result = curry(result, aryKey); } return false; } @@ -252,8 +254,8 @@ function baseConvert(util, name, func, options) { // Iterate over methods for the current ary cap. var pairs = []; - each(mapping.caps, function(cap) { - each(mapping.aryMethod[cap], function(key) { + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(key) { var func = _[mapping.remap[key] || key]; if (func) { pairs.push([key, wrap(key, func)]); diff --git a/fp/_mapping.js b/fp/_mapping.js index 4726799a11..56ac6ef8ec 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -38,55 +38,52 @@ exports.aliasToReal = { /** Used to map ary to method names. */ exports.aryMethod = { - 1: [ - 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', - 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', - 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', - 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' - ], - 2: [ - 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', - 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', - 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', - 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', - 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', - 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', - 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', - 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', - 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', - 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', - 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', - 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', - 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', - 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', - 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', - 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', - 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', - 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', - 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' - ], - 3: [ - 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', - 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', - 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace', - 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', - 'unionWith', 'xorBy', 'xorWith', 'zipWith' - ], - 4: [ - 'fill', 'setWith' - ] + '1': [ + 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', + 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', + 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', + 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' + ], + '2': [ + 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', + 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', + 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', + 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', + 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', + 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', + 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', + 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', + 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', + 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', + 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', + 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', + 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', + 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', + 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', + 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', + 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', + 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', + 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' + ], + '3': [ + 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', + 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', + 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace', + 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', + 'unionWith', 'xorBy', 'xorWith', 'zipWith' + ], + '4': [ + 'fill', 'setWith' + ] }; /** Used to map ary to rearg configs. */ exports.aryRearg = { - 2: [1, 0], - 3: [2, 0, 1], - 4: [3, 2, 0, 1] + '2': [1, 0], + '3': [2, 0, 1], + '4': [3, 2, 0, 1] }; -/** Used to iterate `mapping.aryMethod` keys. */ -exports.caps = [1, 2, 3, 4]; - /** Used to map method names to their iteratee ary. */ exports.iterateeAry = { 'assignWith': 2, From 607fe2a5f6d055a059d56b3585000cd4e1a0b64e Mon Sep 17 00:00:00 2001 From: Graeme Yeates Date: Mon, 15 Feb 2016 19:01:38 -0500 Subject: [PATCH 70/79] Use Object.create in baseCreate (even if shimmed). --- lodash.js | 15 ++++----------- test/index.html | 9 --------- test/test.js | 2 -- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/lodash.js b/lodash.js index 3e82ce668a..24f0e6bfd6 100644 --- a/lodash.js +++ b/lodash.js @@ -1315,6 +1315,7 @@ /** Built-in value references. */ var Buffer = moduleExports ? context.Buffer : undefined, + objectCreate = Object.create, Reflect = context.Reflect, Symbol = context.Symbol, Uint8Array = context.Uint8Array, @@ -2373,17 +2374,9 @@ * @param {Object} prototype The object to inherit from. * @returns {Object} Returns the new object. */ - var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; - }; - }()); + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } /** * The base implementation of `_.delay` and `_.defer` which accepts an array diff --git a/test/index.html b/test/index.html index 8de250eb1f..b17a371085 100644 --- a/test/index.html +++ b/test/index.html @@ -82,9 +82,6 @@ funcProto._method = noop; // Set bad shims. - setProperty(Object, '_create', Object.create); - setProperty(Object, 'create', noop); - setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols); setProperty(Object, 'getOwnPropertySymbols', undefined); @@ -133,11 +130,6 @@ setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable); - if (Object._create) { - Object.create = Object._create; - } else { - delete Object.create; - } if (Object._getOwnPropertySymbols) { Object.getOwnPropertySymbols = Object._getOwnPropertySymbols; } else { @@ -174,7 +166,6 @@ delete funcProto._method; delete objectProto._propertyIsEnumerable; - delete Object._create; delete Object._getOwnPropertySymbols; } diff --git a/test/test.js b/test/test.js index 6542d6fd36..fe161a24b1 100644 --- a/test/test.js +++ b/test/test.js @@ -467,7 +467,6 @@ funcProto._method = noop; // Set bad shims. - setProperty(Object, 'create', noop); var _getOwnPropertySymbols = Object.getOwnPropertySymbols; setProperty(Object, 'getOwnPropertySymbols', undefined); @@ -520,7 +519,6 @@ root._ = oldDash; // Restore built-in methods. - setProperty(Object, 'create', create); setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); setProperty(root, 'Buffer', Buffer); From ba2d3f77047b7b38c45dea93263559e4abbd1d3f Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 16:36:20 -0800 Subject: [PATCH 71/79] Use `!=` instead of `!==` when value is guaranteed to be a string. --- lodash.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lodash.js b/lodash.js index 24f0e6bfd6..28681263af 100644 --- a/lodash.js +++ b/lodash.js @@ -5171,7 +5171,7 @@ function isKeyable(value) { var type = typeof value; return type == 'number' || type == 'boolean' || - (type == 'string' && value !== '__proto__') || value == null; + (type == 'string' && value != '__proto__') || value == null; } /** From 10dd42b6e48f93807d258b59d51ce2d282e11add Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 16:47:21 -0800 Subject: [PATCH 72/79] Restore bizarro tests for `Object.create`. --- lodash.js | 2 +- test/index.html | 21 ++++++++++++++++++++- test/test.js | 14 +++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lodash.js b/lodash.js index 28681263af..4aa0a00d48 100644 --- a/lodash.js +++ b/lodash.js @@ -1315,7 +1315,6 @@ /** Built-in value references. */ var Buffer = moduleExports ? context.Buffer : undefined, - objectCreate = Object.create, Reflect = context.Reflect, Symbol = context.Symbol, Uint8Array = context.Uint8Array, @@ -1324,6 +1323,7 @@ getPrototypeOf = Object.getPrototypeOf, getOwnPropertySymbols = Object.getOwnPropertySymbols, iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, + objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, setTimeout = context.setTimeout, splice = arrayProto.splice; diff --git a/test/index.html b/test/index.html index b17a371085..965da33335 100644 --- a/test/index.html +++ b/test/index.html @@ -82,6 +82,19 @@ funcProto._method = noop; // Set bad shims. + setProperty(Object, '_create', Object.create); + setProperty(Object, 'create', (function() { + function object() {} + return function(prototype) { + if (prototype === Object(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }())); + setProperty(Object, '_getOwnPropertySymbols', Object.getOwnPropertySymbols); setProperty(Object, 'getOwnPropertySymbols', undefined); @@ -130,6 +143,11 @@ setProperty(objectProto, 'propertyIsEnumerable', objectProto._propertyIsEnumerable); + if (Object._create) { + Object.create = Object._create; + } else { + delete Object.create; + } if (Object._getOwnPropertySymbols) { Object.getOwnPropertySymbols = Object._getOwnPropertySymbols; } else { @@ -165,8 +183,9 @@ setProperty(window, 'module', document.getElementById('module')); delete funcProto._method; - delete objectProto._propertyIsEnumerable; + delete Object._create; delete Object._getOwnPropertySymbols; + delete objectProto._propertyIsEnumerable; } // Load lodash to expose it to the bad extensions/shims. diff --git a/test/test.js b/test/test.js index fe161a24b1..d98aedb484 100644 --- a/test/test.js +++ b/test/test.js @@ -458,7 +458,7 @@ // Allow bypassing native checks. setProperty(funcProto, 'toString', function wrapper() { setProperty(funcProto, 'toString', fnToString); - var result = _.has(this, 'toString') ? this.toString() : fnToString.call(this); + var result = lodashStable.has(this, 'toString') ? this.toString() : fnToString.call(this); setProperty(funcProto, 'toString', wrapper); return result; }); @@ -467,6 +467,17 @@ funcProto._method = noop; // Set bad shims. + setProperty(Object, 'create', (function() { + function object() {} + return function(prototype) { + if (lodashStable.isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; + }())); var _getOwnPropertySymbols = Object.getOwnPropertySymbols; setProperty(Object, 'getOwnPropertySymbols', undefined); @@ -519,6 +530,7 @@ root._ = oldDash; // Restore built-in methods. + setProperty(Object, 'create', create); setProperty(objectProto, 'propertyIsEnumerable', _propertyIsEnumerable); setProperty(root, 'Buffer', Buffer); From 01d530d65e2a7a20a7be97dcf6d143299608b1e3 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 16:59:43 -0800 Subject: [PATCH 73/79] Cleanup fp/build-modules. --- lib/fp/build-modules.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/fp/build-modules.js b/lib/fp/build-modules.js index 36a8a741f6..1d2ce6b4cb 100644 --- a/lib/fp/build-modules.js +++ b/lib/fp/build-modules.js @@ -87,6 +87,8 @@ function onComplete(error) { } function build(target) { + target = path.resolve(target); + var fpPath = path.join(target, 'fp'); // Glob existing lodash module paths. @@ -100,14 +102,14 @@ function build(target) { // Add FP alias and remapped module paths. _.each([mapping.aliasToReal, mapping.remap], function(data) { _.forOwn(data, function(realName, alias) { - if (!_.startsWith(alias, '_')) { - modulePaths.push(path.join(target, alias + '.js')); + var modulePath = path.join(target, alias + '.js'); + if (!_.startsWith(alias, '_') && + !_.includes(modulePaths, modulePath)) { + modulePaths.push(modulePath); } }); }); - modulePaths = _.uniq(modulePaths); - var actions = modulePaths.map(function(modulePath) { var moduleName = path.basename(modulePath, '.js'); return writeFile(path.join(fpPath, moduleName + '.js'), getTemplate(moduleName)); From 0da3674d5e9418cd0e51ce7ccfc895224c2a2edd Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 17:00:01 -0800 Subject: [PATCH 74/79] Update fp doc template. --- lib/fp/build-doc.js | 33 ++++++++++---- lib/fp/template/doc/wiki.jst | 84 ++++++++++++++++++++++++++++++------ 2 files changed, 96 insertions(+), 21 deletions(-) diff --git a/lib/fp/build-doc.js b/lib/fp/build-doc.js index b67c881326..bba62d2e61 100644 --- a/lib/fp/build-doc.js +++ b/lib/fp/build-doc.js @@ -5,29 +5,45 @@ var _ = require('lodash'), path = require('path'), util = require('../common/util'); -var basePath = path.join(__dirname, '..', '..'), - docPath = path.join(basePath, 'doc'), - readmePath = path.join(docPath, 'FP-Guide.md'); - var mapping = require('../../fp/_mapping'), templatePath = path.join(__dirname, 'template/doc'), template = util.globTemplate(path.join(templatePath, '*.jst')); +var argNames = ['a', 'b', 'c', 'd']; + var templateData = { 'mapping': mapping, + 'toArgOrder': toArgOrder, 'toFuncList': toFuncList }; +function toArgOrder(array) { + return '`(' + _.map(array, function(value) { + return argNames[value]; + }).join(', ') + ')`'; +} + function toFuncList(array) { var chunks = _.chunk(array.slice().sort(), 5), lastChunk = _.last(chunks), last = lastChunk ? lastChunk.pop() : undefined; + chunks = _.reject(chunks, _.isEmpty); + lastChunk = _.last(chunks); + var result = '`' + _.map(chunks, function(chunk) { return chunk.join('`, `') + '`'; }).join(',\n`'); - return result + (last == null ? '' : (', & `' + last + '`')); + if (last == null) { + return result; + } + if (_.size(chunks) > 1 || _.size(lastChunk) > 1) { + result += ','; + } + result += ' &'; + result += _.size(lastChunk) < 5 ? ' ' : '\n'; + return result + '`' + last + '`'; } /*----------------------------------------------------------------------------*/ @@ -38,8 +54,9 @@ function onComplete(error) { } } -function build() { - fs.writeFile(readmePath, template.wiki(templateData), onComplete); +function build(target) { + target = path.resolve(target); + fs.writeFile(target, template.wiki(templateData), onComplete); } -build(); +build(_.last(process.argv)); diff --git a/lib/fp/template/doc/wiki.jst b/lib/fp/template/doc/wiki.jst index 6cc54e554d..abb7456bdb 100644 --- a/lib/fp/template/doc/wiki.jst +++ b/lib/fp/template/doc/wiki.jst @@ -1,7 +1,7 @@ ## lodash/fp -The lodash/fp module is an instance of lodash with its methods wrapped to produce -immutable auto-curried iteratee-first data-last methods. +The `lodash/fp` module is an instance of `lodash` with its methods wrapped to +produce immutable auto-curried iteratee-first data-last methods. ## Installation @@ -13,30 +13,74 @@ In a browser: In Node.js: ```js -// load the fp build +// Load the fp build. var _ = require('lodash/fp'); -// or a method category -var array = require('lodash/fp/object'); +// Load a method category. +var object = require('lodash/fp/object'); -// or method for smaller builds with browserify/rollup/webpack +// Load a single method for smaller builds with browserify/rollup/webpack. var extend = require('lodash/fp/extend'); ``` +## Convert + +This module is used to convert Lodash methods into their `fp` counterparts. +```js +var convert = require('lodash/fp/convert'); + +// Convert by name. +var assign = convert('assign', require('lodash.assign')); + +// Convert by object. +var fp = convert({ + 'assign': require('lodash.assign'), + 'chunk': require('lodash.chunk') +}); + +// Convert by `lodash` instance. +var fp = convert(lodash.runInContext()); +``` + +It’s customizable to create the `fp` wrapper that’s right for you. +```js +// Every option is `true` by default. +var filter = convert('filter', _.filter, { + // Specify capping iteratee arguments. + 'cap': true, + // Specify currying. + 'curry': true, + // Specify fixed arity. + 'fixed': true, + // Specify immutable operations. + 'immutable': true, + // Specify rearranging arguments. + 'rearg': true +}); + +// Set `cap` to `false` to create a wrapper that doesn’t cap iteratee arguments. +var filter = convert('filter', _.filter, { 'cap': false }); + +filter(function(value, index) { + return index % 2 == 0; +})(['a', 'b', 'c']); +// => ['a', 'c'] +``` + ## Notes #### Arity -Methods with arity capped to one argument:
+Methods with arity fixed to one argument:
<%= toFuncList(mapping.aryMethod[1]) %> -Methods with arity capped to two arguments:
+Methods with arity fixed to two arguments:
<%= toFuncList(mapping.aryMethod[2]) %> -Methods with arity capped to three arguments:
+Methods with arity fixed to three arguments:
<%= toFuncList(mapping.aryMethod[3]) %> -Methods with arity capped to four arguments:
+Methods with arity fixed to four arguments:
<%= toFuncList(mapping.aryMethod[4]) %> #### Iteratees @@ -52,14 +96,28 @@ Methods which provide iteratees two argument:
Methods created to accommodate Lodash’s variadic methods:
<%= toFuncList(_.keys(mapping.remap)) %> -#### Exceptions +#### Argument Orders + +Methods fixed to two arguments have an argument order of
+<%= toArgOrder(mapping.aryRearg[2]) %> + +Methods fixed to three arguments have an argument order of
+<%= toArgOrder(mapping.aryRearg[3]) %> + +Methods fixed to four arguments have an argument order of
+<%= toArgOrder(mapping.aryRearg[4]) %> + +Methods with custom argument orders:
+<%= _.map(mapping.methodRearg, function(orders, methodName) { + return ' * `_.' + methodName + '` has an order of ' + toArgOrder(orders); +}).join('\n') %> -Methods which have argument order unchanged:
+Methods with unchanged argument orders:
<%= toFuncList(_.keys(mapping.skipRearg)) %> #### Aliases There are <%= _.size(mapping.aliasToReal) %> method aliases:
<%= _.map(mapping.aliasToReal, function(realName, alias) { - return ' - Added `_.' + alias + '` as an alias of `_.' + realName + '`'; + return ' * Added `_.' + alias + '` as an alias of `_.' + realName + '`'; }).join('\n') %> From 97fd94744e0f3025dfc4f09fe05d8d69e45a1f7c Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 17:38:30 -0800 Subject: [PATCH 75/79] Add mapping section to fp wiki template. [ci skip] --- lib/fp/template/doc/wiki.jst | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/fp/template/doc/wiki.jst b/lib/fp/template/doc/wiki.jst index abb7456bdb..d5be1124cf 100644 --- a/lib/fp/template/doc/wiki.jst +++ b/lib/fp/template/doc/wiki.jst @@ -25,7 +25,7 @@ var extend = require('lodash/fp/extend'); ## Convert -This module is used to convert Lodash methods into their `fp` counterparts. +This module is used to convert Lodash methods to their `fp` counterparts. ```js var convert = require('lodash/fp/convert'); @@ -42,7 +42,7 @@ var fp = convert({ var fp = convert(lodash.runInContext()); ``` -It’s customizable to create the `fp` wrapper that’s right for you. +It’s even customizable so you can create the `fp` function that’s right for you. ```js // Every option is `true` by default. var filter = convert('filter', _.filter, { @@ -58,7 +58,7 @@ var filter = convert('filter', _.filter, { 'rearg': true }); -// Set `cap` to `false` to create a wrapper that doesn’t cap iteratee arguments. +// Specify `cap` of `false` to create a function that doesn’t cap iteratee arguments. var filter = convert('filter', _.filter, { 'cap': false }); filter(function(value, index) { @@ -67,9 +67,21 @@ filter(function(value, index) { // => ['a', 'c'] ``` -## Notes +## Mapping -#### Arity +Immutable auto-curried iteratee-first data-last methods sound great, but what’s +that really mean for each method? Below is a breakdown of the mapping used to +convert each method. + +#### Capped Iteratee Arguments + +Methods which provide iteratees one argument:
+<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 1)))) %> + +Methods which provide iteratees two arguments:
+<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 2)))) %> + +#### Fixed Arity Methods with arity fixed to one argument:
<%= toFuncList(mapping.aryMethod[1]) %> @@ -83,20 +95,7 @@ Methods with arity fixed to three arguments:
Methods with arity fixed to four arguments:
<%= toFuncList(mapping.aryMethod[4]) %> -#### Iteratees - -Methods which provide iteratees one argument:
-<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 1)))) %> - -Methods which provide iteratees two argument:
-<%= toFuncList(_.keys(_.pick(mapping.iterateeAry, _.partial(_.eq, _, 2)))) %> - -#### New Methods - -Methods created to accommodate Lodash’s variadic methods:
-<%= toFuncList(_.keys(mapping.remap)) %> - -#### Argument Orders +#### Rearranged Arguments Methods fixed to two arguments have an argument order of
<%= toArgOrder(mapping.aryRearg[2]) %> @@ -115,6 +114,11 @@ Methods with custom argument orders:
Methods with unchanged argument orders:
<%= toFuncList(_.keys(mapping.skipRearg)) %> +#### New Methods + +Methods created to accommodate Lodash’s variadic methods:
+<%= toFuncList(_.keys(mapping.remap)) %> + #### Aliases There are <%= _.size(mapping.aliasToReal) %> method aliases:
From 5dd6b9069202ea32adc80f4dfd77dbbb44c823fe Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 21:29:01 -0800 Subject: [PATCH 76/79] Minor comma nit from contributing.md. [ci skip] --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d55dd8cfbc..2fd78f8ee0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing to Lodash -Contributions are always welcome. Before contributing, please read the +Contributions are always welcome. Before contributing please read the [code of conduct](https://github.com/lodash/lodash/blob/master/CODE_OF_CONDUCT.md) & [search the issue tracker](https://github.com/lodash/lodash/issues); your issue may have already been discussed or fixed in `master`. To contribute, From 09dd3a8fea3826a27b6e3ef1bf8789c626d38709 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 23:06:28 -0800 Subject: [PATCH 77/79] Remove `noConflict` call from the node fp module template. --- lib/fp/template/modules/fp.jst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fp/template/modules/fp.jst b/lib/fp/template/modules/fp.jst index d8887e0fe7..39196b9930 100644 --- a/lib/fp/template/modules/fp.jst +++ b/lib/fp/template/modules/fp.jst @@ -1,2 +1,2 @@ -var _ = require('./lodash').noConflict().runInContext(); +var _ = require('./lodash').runInContext(); module.exports = require('./fp/convert')(_); From 36af8de1162f4cde7f3111396c4e81aeaea0b4f3 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 20:06:19 -0800 Subject: [PATCH 78/79] Rebuild lodash and docs. --- dist/lodash.core.js | 175 +++++---- dist/lodash.core.min.js | 51 ++- dist/lodash.fp.js | 230 +++++------ dist/lodash.fp.min.js | 24 +- dist/lodash.js | 585 ++++++++++++++++++---------- dist/lodash.min.js | 212 +++++----- dist/mapping.fp.js | 104 +++-- doc/README.md | 828 ++++++++++++++++++++++------------------ lodash.js | 4 +- package.json | 2 +- 10 files changed, 1228 insertions(+), 987 deletions(-) diff --git a/dist/lodash.core.js b/dist/lodash.core.js index ee2a004e74..963c9c72c5 100644 --- a/dist/lodash.core.js +++ b/dist/lodash.core.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.3.0 (Custom Build) + * lodash 4.4.0 (Custom Build) * Build: `lodash core -o ./dist/lodash.core.js` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '4.3.0'; + var VERSION = '4.4.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -27,7 +27,8 @@ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER = 9007199254740991; + var INFINITY = 1 / 0, + MAX_SAFE_INTEGER = 9007199254740991; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', @@ -66,10 +67,19 @@ }; /** Detect free variable `exports`. */ - var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null; + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; /** Detect free variable `module`. */ - var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null; + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; /** Detect free variable `global` from Node.js. */ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); @@ -80,9 +90,6 @@ /** Detect free variable `window`. */ var freeWindow = checkGlobal(objectTypes[typeof window] && window); - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null; - /** Detect `this` as the global object. */ var thisGlobal = checkGlobal(objectTypes[typeof this] && this); @@ -92,7 +99,9 @@ * The `this` value is used if it's the global object to avoid Greasemonkey's * restricted `window` object, otherwise the `window` object is used. */ - var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')(); + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); /*--------------------------------------------------------------------------*/ @@ -365,6 +374,7 @@ Symbol = root.Symbol, Uint8Array = root.Uint8Array, enumerate = Reflect ? Reflect.enumerate : undefined, + objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable; /* Built-in method references for those with the same name as other `lodash` methods. */ @@ -413,28 +423,28 @@ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, - * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`, - * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`, - * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, - * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`, - * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, - * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, - * `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, - * `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, - * `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, - * `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`, - * `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`, - * `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, - * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, - * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, - * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, - * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, - * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, - * `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, - * `zipObjectDeep`, and `zipWith` + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, + * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, + * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, + * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, + * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, + * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, + * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, + * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`, + * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, + * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, + * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, + * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`, + * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, + * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, @@ -549,6 +559,17 @@ } } + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + /** * The base implementation of `_.create` without support for assigning * properties to the created object. @@ -557,17 +578,9 @@ * @param {Object} prototype The object to inherit from. * @returns {Object} Returns the new object. */ - var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; - }; - }()); + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } /** * The base implementation of `_.delay` and `_.defer` which accepts an array @@ -636,12 +649,12 @@ * * @private * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. + * @param {number} depth The maximum recursion depth. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict, result) { + function baseFlatten(array, depth, isStrict, result) { result || (result = []); var index = -1, @@ -649,11 +662,11 @@ while (++index < length) { var value = array[index]; - if (isArrayLikeObject(value) && + if (depth > 0 && isArrayLikeObject(value) && (isStrict || isArray(value) || isArguments(value))) { - if (isDeep) { + if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, isDeep, isStrict, result); + baseFlatten(value, depth - 1, isStrict, result); } else { arrayPush(result, value); } @@ -816,7 +829,6 @@ * property of prototypes or treat sparse arrays as dense. * * @private - * @type Function * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ @@ -1032,8 +1044,11 @@ length = props.length; while (++index < length) { - var key = props[index], - newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key]; + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; assignValue(object, key, newValue); } @@ -1053,7 +1068,10 @@ length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined; - customizer = typeof customizer == 'function' ? (length--, customizer) : undefined; + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + object = Object(object); while (++index < length) { var source = sources[index]; @@ -1382,17 +1400,6 @@ return value === proto; } - /** - * Converts `value` to a function if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Function} Returns the function. - */ - function toFunction(value) { - return typeof value == 'function' ? value : identity; - } - /** * Creates a clone of `wrapper`. * @@ -1451,12 +1458,12 @@ if (!isArray(array)) { array = array == null ? [] : [Object(array)]; } - values = baseFlatten(values); + values = baseFlatten(values, 1); return arrayConcat(array, values); }); /** - * Flattens `array` a single level. + * Flattens `array` a single level deep. * * @static * @memberOf _ @@ -1465,30 +1472,30 @@ * @returns {Array} Returns the new flattened array. * @example * - * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]] + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] */ function flatten(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array) : []; + return length ? baseFlatten(array, 1) : []; } /** - * This method is like `_.flatten` except that it recursively flattens `array`. + * Recursively flattens `array`. * * @static * @memberOf _ * @category Array - * @param {Array} array The array to recursively flatten. + * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; + return length ? baseFlatten(array, INFINITY) : []; } /** @@ -1872,7 +1879,7 @@ * // => logs 'a' then 'b' (iteration order is not guaranteed) */ function forEach(collection, iteratee) { - return baseEach(collection, toFunction(iteratee)); + return baseEach(collection, baseCastFunction(iteratee)); } /** @@ -2400,7 +2407,7 @@ * * @static * @memberOf _ - * @type Function + * @type {Function} * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. @@ -2427,7 +2434,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. @@ -2456,7 +2462,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. @@ -2548,7 +2553,8 @@ */ function isEmpty(value) { if (isArrayLike(value) && - (isArray(value) || isString(value) || isFunction(value.splice) || isArguments(value))) { + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { return !value.length; } for (var key in value) { @@ -2667,7 +2673,8 @@ * // => false */ function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** @@ -3295,7 +3302,7 @@ * // => { 'a': 1, 'c': 3 } */ var pick = rest(function(object, props) { - return object == null ? {} : basePick(object, baseFlatten(props)); + return object == null ? {} : basePick(object, baseFlatten(props, 1)); }); /** @@ -3429,7 +3436,8 @@ * Creates a function that invokes `func` with the arguments of the created * function. If `func` is a property name the created callback returns the * property value for a given element. If `func` is an object the created - * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`. + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. * * @static * @memberOf _ @@ -3457,9 +3465,10 @@ var iteratee = baseIteratee; /** - * Creates a function that performs a deep partial comparison between a given + * Creates a function that performs a partial deep comparison between a given * object and `source`, returning `true` if the given object has equivalent - * property values, else `false`. + * property values, else `false`. The created function is equivalent to + * `_.isMatch` with a `source` partially applied. * * **Note:** This method supports comparing the same values as `_.isEqual`. * @@ -3597,7 +3606,7 @@ * @static * @memberOf _ * @category Util - * @param {string} [prefix] The value to prefix the ID with. + * @param {string} [prefix=''] The value to prefix the ID with. * @returns {string} Returns the unique ID. * @example * @@ -3759,7 +3768,7 @@ * * @static * @memberOf _ - * @type string + * @type {string} */ lodash.VERSION = VERSION; diff --git a/dist/lodash.core.min.js b/dist/lodash.core.min.js index 889fc25b32..8dffb187a6 100644 --- a/dist/lodash.core.min.js +++ b/dist/lodash.core.min.js @@ -1,30 +1,29 @@ /** * @license - * lodash 4.3.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * lodash 4.4.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE * Build: `lodash core -o ./dist/lodash.core.js` */ -;(function(){function n(n,t){for(var r=-1,e=t.length,u=n.length;++r-1&&0==n%1&&(null==t?9007199254740991:t)>n}function a(n){if(Y(n)&&!Mn(n)){if(n instanceof l)return n;if(xn.call(n,"__wrapped__")){var t=new l(n.__wrapped__,n.__chain__);return t.__actions__=k(n.__actions__),t}}return new l(n)}function l(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function p(n,t,r,e){return n===an||V(n,On[r])&&!xn.call(e,r)?t:n; -}function s(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function");return setTimeout(function(){n.apply(an,r)},t)}function h(n,t){var r=true;return In(n,function(n,e,u){return r=!!t(n,e,u)}),r}function v(n,t){var r=[];return In(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function y(t,r,e,u){u||(u=[]);for(var o=-1,i=t.length;++ot&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e1?r[u-1]:an,o=typeof o=="function"?(u--,o):an;for(t=Object(t);++ef))return false;for(a=true;++iarguments.length,In)}function P(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Pn(n), -function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=an),r}}function U(n){var t;if(typeof n!="function")throw new TypeError("Expected a function");return t=Rn(t===an?n.length-1:Pn(t),0),function(){for(var r=arguments,e=-1,u=Rn(r.length-t,0),o=Array(u);++et}function K(n){return Y(n)&&L(n)&&xn.call(n,"callee")&&(!Tn.call(n,"callee")||"[object Arguments]"==An.call(n)); -}function L(n){return null!=n&&!(typeof n=="function"&&Q(n))&&W(qn(n))}function Q(n){return n=X(n)?An.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function W(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function X(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function Y(n){return!!n&&typeof n=="object"}function Z(n){return typeof n=="number"||Y(n)&&"[object Number]"==An.call(n)}function nn(n){return typeof n=="string"||!Mn(n)&&Y(n)&&"[object String]"==An.call(n); -}function tn(n,t){return t>n}function rn(n){return typeof n=="string"?n:null==n?"":n+""}function en(n){var t=z(n);if(!t&&!L(n))return Bn(Object(n));var r,e=q(n),u=!!e,e=e||[],o=e.length;for(r in n)!xn.call(n,r)||u&&("length"==r||f(r,o))||t&&"constructor"==r||e.push(r);return e}function un(n){for(var t=-1,r=z(n),e=d(n),u=e.length,o=q(n),i=!!o,o=o||[],c=o.length;++t"'`]/g,pn=RegExp(ln.source),sn=/^(?:0|[1-9]\d*)$/,hn={ -"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},vn={"function":true,object:true},yn=vn[typeof exports]&&exports&&!exports.nodeType?exports:null,_n=vn[typeof module]&&module&&!module.nodeType?module:null,gn=o(vn[typeof self]&&self),bn=o(vn[typeof window]&&window),jn=_n&&_n.exports===yn?yn:null,mn=o(vn[typeof this]&&this),dn=o(yn&&_n&&typeof global=="object"&&global)||bn!==(mn&&mn.window)&&bn||gn||mn||Function("return this")(),wn=Array.prototype,On=Object.prototype,xn=On.hasOwnProperty,En=0,An=On.toString,kn=dn._,Nn=dn.f,Sn=Nn?Nn.g:an,Tn=On.propertyIsEnumerable,Fn=dn.isFinite,Bn=Object.keys,Rn=Math.max,Dn=function(){ -function n(){}return function(t){if(X(t)){n.prototype=t;var r=new n;n.prototype=an}return r||{}}}(),In=function(n,t){return function(r,e){if(null==r)return r;if(!L(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++oe&&!c||!i||u&&!f&&a||o&&a){ -r=1;break n}if(e>r&&!u||!a||c&&!o&&i||f&&i){r=-1;break n}}r=0}return r||n.b-t.b}),E("c"))},a.tap=function(n,t){return t(n),n},a.thru=function(n,t){return t(n)},a.toArray=function(n){return L(n)?n.length?k(n):[]:on(n)},a.values=on,a.extend=Hn,fn(a,a),a.clone=function(n){return X(n)?Mn(n)?k(n):T(n,en(n)):n},a.escape=function(n){return(n=rn(n))&&pn.test(n)?n.replace(ln,i):n},a.every=function(n,t,r){return t=r?an:t,h(n,m(t))},a.find=G,a.forEach=J,a.has=function(n,t){return null!=n&&xn.call(n,t)},a.head=C, -a.identity=cn,a.indexOf=function(n,t,r){var e=n?n.length:0;r=typeof r=="number"?0>r?Rn(e+r,0):r:0,r=(r||0)-1;for(var u=t===t;++r-1&&0==n%1&&(null==t?9007199254740991:t)>n}function a(n){if(Z(n)&&!Un(n)){if(n instanceof l)return n;if(An.call(n,"__wrapped__")){var t=new l(n.__wrapped__,n.__chain__);return t.__actions__=N(n.__actions__),t}}return new l(n)}function l(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t}function p(n,t,r,e){return n===ln||H(n,En[r])&&!An.call(e,r)?t:n; +}function s(n){return Y(n)?Rn(n):{}}function h(n,t,r){if(typeof n!="function")throw new TypeError("Expected a function");return setTimeout(function(){n.apply(ln,r)},t)}function v(n,t){var r=true;return qn(n,function(n,e,u){return r=!!t(n,e,u)}),r}function y(n,t){var r=[];return qn(n,function(n,e,u){t(n,e,u)&&r.push(n)}),r}function _(t,r,e,u){u||(u=[]);for(var o=-1,i=t.length;++o0&&Z(c)&&Q(c)&&(e||Un(c)||L(c))?r>1?_(c,r-1,e,u):n(u,c):e||(u[u.length]=c)}return u}function g(n,t){return n&&zn(n,t,un); +}function b(n,t){return y(t,function(t){return W(n[t])})}function j(n,t,r,e,u){return n===t?true:null==n||null==t||!Y(n)&&!Z(t)?n!==n&&t!==t:m(n,t,j,r,e,u)}function m(n,t,r,e,u,o){var i=Un(n),f=Un(t),a="[object Array]",l="[object Array]";i||(a=Nn.call(n),"[object Arguments]"==a&&(a="[object Object]")),f||(l=Nn.call(t),"[object Arguments]"==l&&(l="[object Object]"));var p="[object Object]"==a&&!c(n),f="[object Object]"==l&&!c(t);return!(l=a==l)||i||p?2&u||(a=p&&An.call(n,"__wrapped__"),f=f&&An.call(t,"__wrapped__"), +!a&&!f)?l?(o||(o=[]),(a=J(o,function(t){return t[0]===n}))&&a[1]?a[1]==t:(o.push([n,t]),t=(i?I:q)(n,t,r,e,u,o),o.pop(),t)):false:r(a?n.value():n,f?t.value():t,e,u,o):$(n,t,a)}function d(n){var t=typeof n;return"function"==t?n:null==n?fn:("object"==t?x:A)(n)}function w(n){n=null==n?n:Object(n);var t,r=[];for(t in n)r.push(t);return r}function O(n,t){var r=-1,e=Q(n)?Array(n.length):[];return qn(n,function(n,u,o){e[++r]=t(n,u,o)}),e}function x(n){var t=un(n);return function(r){var e=t.length;if(null==r)return!e; +for(r=Object(r);e--;){var u=t[e];if(!(u in r&&j(n[u],r[u],ln,3)))return false}return true}}function E(n,t){return n=Object(n),P(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function A(n){return function(t){return null==t?ln:t[n]}}function k(n,t,r){var e=-1,u=n.length;for(0>t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e1?r[u-1]:ln,o=typeof o=="function"?(u--,o):ln;for(t=Object(t);++ef))return false;for(a=true;++iarguments.length,qn)}function U(n,t){var r;if(typeof t!="function")throw new TypeError("Expected a function");return n=Vn(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=ln),r}}function V(n){var t;if(typeof n!="function")throw new TypeError("Expected a function");return t=$n(t===ln?n.length-1:Vn(t),0),function(){for(var r=arguments,e=-1,u=$n(r.length-t,0),o=Array(u);++et}function L(n){return Z(n)&&Q(n)&&An.call(n,"callee")&&(!Bn.call(n,"callee")||"[object Arguments]"==Nn.call(n))}function Q(n){return null!=n&&!(typeof n=="function"&&W(n))&&X(Cn(n))}function W(n){return n=Y(n)?Nn.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function X(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function Y(n){ +var t=typeof n;return!!n&&("object"==t||"function"==t)}function Z(n){return!!n&&typeof n=="object"}function nn(n){return typeof n=="number"||Z(n)&&"[object Number]"==Nn.call(n)}function tn(n){return typeof n=="string"||!Un(n)&&Z(n)&&"[object String]"==Nn.call(n)}function rn(n,t){return t>n}function en(n){return typeof n=="string"?n:null==n?"":n+""}function un(n){var t=C(n);if(!t&&!Q(n))return In(Object(n));var r,e=z(n),u=!!e,e=e||[],o=e.length;for(r in n)!An.call(n,r)||u&&("length"==r||f(r,o))||t&&"constructor"==r||e.push(r); +return e}function on(n){for(var t=-1,r=C(n),e=w(n),u=e.length,o=z(n),i=!!o,o=o||[],c=o.length;++t"'`]/g,hn=RegExp(sn.source),vn=/^(?:0|[1-9]\d*)$/,yn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},_n={"function":true,object:true},gn=_n[typeof exports]&&exports&&!exports.nodeType?exports:ln,bn=_n[typeof module]&&module&&!module.nodeType?module:ln,jn=bn&&bn.exports===gn?gn:ln,mn=o(_n[typeof self]&&self),dn=o(_n[typeof window]&&window),wn=o(_n[typeof this]&&this),On=o(gn&&bn&&typeof global=="object"&&global)||dn!==(wn&&wn.window)&&dn||mn||wn||Function("return this")(),xn=Array.prototype,En=Object.prototype,An=En.hasOwnProperty,kn=0,Nn=En.toString,Sn=On._,Tn=On.Reflect,Fn=Tn?Tn.f:ln,Rn=Object.create,Bn=En.propertyIsEnumerable,Dn=On.isFinite,In=Object.keys,$n=Math.max,qn=function(n,t){ +return function(r,e){if(null==r)return r;if(!Q(r))return n(r,e);for(var u=r.length,o=t?u:-1,i=Object(r);(t?o--:++oe&&!c||!i||u&&!f&&a||o&&a){r=1;break n}if(e>r&&!u||!a||c&&!o&&i||f&&i){r=-1;break n}}r=0}return r||n.b-t.b; +}),A("c"))},a.tap=function(n,t){return t(n),n},a.thru=function(n,t){return t(n)},a.toArray=function(n){return Q(n)?n.length?N(n):[]:cn(n)},a.values=cn,a.extend=Ln,an(a,a),a.clone=function(n){return Y(n)?Un(n)?N(n):F(n,un(n)):n},a.escape=function(n){return(n=en(n))&&hn.test(n)?n.replace(sn,i):n},a.every=function(n,t,r){return t=r?ln:t,v(n,d(t))},a.find=J,a.forEach=M,a.has=function(n,t){return null!=n&&An.call(n,t)},a.head=G,a.identity=fn,a.indexOf=function(n,t,r){var e=n?n.length:0;r=typeof r=="number"?0>r?$n(e+r,0):r:0, +r=(r||0)-1;for(var u=t===t;++r 1 && (forceRearg || !mapping.skipRearg[name])) { - result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]); + if (config.rearg && aryKey > 1 && (forceRearg || !mapping.skipRearg[name])) { + result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[aryKey]); } - if (config.cap) { - if (reargIndexes) { - result = iterateeRearg(result, reargIndexes); - } else if (aryN) { - result = iterateeAry(result, aryN); - } + if (config.cap && aryN) { + result = iterateeAry(result, aryN); } - if (config.curry && cap > 1) { - result = curry(result, cap); + if (config.curry && aryKey > 1) { + result = curry(result, aryKey); } return false; } @@ -297,24 +318,24 @@ return /******/ (function(modules) { // webpackBootstrap return !result; }); - result || (result = func); + result || (result = wrapped); if (mapping.placeholder[name]) { + setPlaceholder = true; func.placeholder = result.placeholder = placeholder; } return result; }; - if (!isLib) { + if (!isObj) { return wrap(name, func); } - // Add placeholder. - _.placeholder = placeholder; + var _ = func; // Iterate over methods for the current ary cap. var pairs = []; - each(mapping.caps, function(cap) { - each(mapping.aryMethod[cap], function(key) { - var func = _[mapping.rename[key] || key]; + each(aryMethodKeys, function(aryKey) { + each(mapping.aryMethod[aryKey], function(key) { + var func = _[mapping.remap[key] || key]; if (func) { pairs.push([key, wrap(key, func)]); } @@ -326,6 +347,9 @@ return /******/ (function(modules) { // webpackBootstrap _[pair[0]] = pair[1]; }); + if (setPlaceholder) { + _.placeholder = placeholder; + } // Wrap the lodash method and its aliases. each(keys(_), function(key) { each(mapping.realToAlias[key] || [], function(alias) { @@ -383,55 +407,52 @@ return /******/ (function(modules) { // webpackBootstrap /** Used to map ary to method names. */ exports.aryMethod = { - 1: [ - 'attempt', 'ceil', 'create', 'curry', 'curryRight', 'floor', 'fromPairs', - 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', 'over', - 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', - 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' - ], - 2: [ - 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', - 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', - 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', - 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', - 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', - 'findLastKey', 'flatMap', 'forEach', 'forEachRight', 'forIn', 'forInRight', - 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', - 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', - 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', - 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', - 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', - 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', - 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', - 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', - 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', - 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', - 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', - 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', - 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' - ], - 3: [ - 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', - 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', - 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace', - 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', - 'unionWith', 'xorBy', 'xorWith', 'zipWith' - ], - 4: [ - 'fill', 'setWith' - ] + '1': [ + 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', + 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', + 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', + 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' + ], + '2': [ + 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', + 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', + 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', + 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', + 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', + 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', + 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', + 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', + 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', + 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', + 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', + 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', + 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', + 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', + 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', + 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', + 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', + 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', + 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' + ], + '3': [ + 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', + 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', + 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace', + 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', + 'unionWith', 'xorBy', 'xorWith', 'zipWith' + ], + '4': [ + 'fill', 'setWith' + ] }; /** Used to map ary to rearg configs. */ exports.aryRearg = { - 2: [1, 0], - 3: [2, 1, 0], - 4: [3, 2, 0, 1] + '2': [1, 0], + '3': [2, 0, 1], + '4': [3, 2, 0, 1] }; - /** Used to iterate `mapping.aryMethod` keys. */ - exports.caps = [1, 2, 3, 4]; - /** Used to map method names to their iteratee ary. */ exports.iterateeAry = { 'assignWith': 2, @@ -472,25 +493,18 @@ return /******/ (function(modules) { // webpackBootstrap 'transform': 2 }; - /** Used to map method names to iteratee rearg configs. */ - exports.iterateeRearg = { - 'findKey': [1], - 'findLastKey': [1], - 'mapKeys': [1] - }; - /** Used to map method names to rearg configs. */ exports.methodRearg = { 'assignInWith': [1, 2, 0], 'assignWith': [1, 2, 0], - 'clamp': [2, 0, 1], + 'getOr': [2, 1, 0], + 'isMatchWith': [2, 1, 0], 'mergeWith': [1, 2, 0], - 'reduce': [2, 0, 1], - 'reduceRight': [2, 0, 1], - 'set': [2, 0, 1], + 'pullAllBy': [2, 1, 0], 'setWith': [3, 1, 2, 0], - 'slice': [2, 0, 1], - 'transform': [2, 0, 1] + 'sortedIndexBy': [2, 1, 0], + 'sortedLastIndexBy': [2, 1, 0], + 'zipWith': [1, 2, 0] }; /** Used to map method names to spread configs. */ @@ -555,7 +569,7 @@ return /******/ (function(modules) { // webpackBootstrap }()); /** Used to map method names to other names. */ - exports.rename = { + exports.remap = { 'curryN': 'curry', 'curryRightN': 'curryRight', 'getOr': 'get', diff --git a/dist/lodash.fp.min.js b/dist/lodash.fp.min.js index b5ddeed5a0..1a4913d56e 100644 --- a/dist/lodash.fp.min.js +++ b/dist/lodash.fp.min.js @@ -1,12 +1,12 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.fp=t():e.fp=t()}(this,function(){return function(e){function t(i){if(r[i])return r[i].exports;var n=r[i]={exports:{},id:i,loaded:!1};return e[i].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){function i(e,t){return n(e,e,void 0,t)}var n=r(1);e.exports=i},function(e,t,r){ -function i(e,t,r,s){if(s||(s={}),"function"!=typeof r&&(r=t,t=void 0),null==r)throw new TypeError;var u={cap:"cap"in s?s.cap:!0,curry:"curry"in s?s.curry:!0,fixed:"fixed"in s?s.fixed:!0,immutable:"immutable"in s?s.immutable:!0,rearg:"rearg"in s?s.rearg:!0},c="rearg"in s&&s.rearg,p=void 0===t&&"string"==typeof r.VERSION,l=p?r:{ary:e.ary,cloneDeep:e.cloneDeep,curry:e.curry,forEach:e.forEach,isFunction:e.isFunction,iteratee:e.iteratee,keys:e.keys,rearg:e.rearg,spread:e.spread},f=l.ary,h=l.cloneDeep,d=l.curry,g=l.forEach,y=l.isFunction,m=l.keys,v=l.rearg,R=l.spread,W=function(e,t){ -return 2==t?function(t,r){return e.apply(void 0,arguments)}:function(t){return e.apply(void 0,arguments)}},x=function(e,t){return 2==t?function(t,r){return e(t,r)}:function(t){return e(t)}},I=function(e){for(var t=e?e.length:0,r=Array(t);t--;)r[t]=e[t];return r},O=function(e){return function(t){return e({},t)}},b=function(e,t){return k(e,t,!0)},E=function(e,t){return k(e,function(e){return x(e,t)})},B=function(e,t){return k(e,function(e){var r=t.length;return W(v(x(e,r),t),r)})},k=function(e,t,r){ -return function(){for(var i=arguments.length,n=Array(i);i--;)n[i]=arguments[i];n[0]=t(n[0]);var a=e.apply(void 0,n);return r?n[0]:a}},j={iteratee:function(e){return function(){var t=arguments[0],r=arguments[1];if(!u.cap)return e(t,r);r=r>2?r-2:1,t=e(t);var i=t.length;return i&&r>=i?t:x(t,r)}},mixin:function(e){return function(t){var r=this;if(!y(r))return e(r,Object(t));var i=[],n=[];return g(m(t),function(e){var a=t[e];y(a)&&(n.push(e),i.push(r.prototype[e]))}),e(r,Object(t)),g(n,function(e,t){var n=i[t]; -y(n)?r.prototype[e]=n:delete r.prototype[e]}),r}},runInContext:function(t){return function(r){return i(e,t(r),void 0,s)}}},A=function(e,t){e=n.aliasToReal[e]||e;var r=j[e];if(r)return r(t);var i=t;u.immutable&&(a.array[e]?i=b(t,I):a.object[e]?i=b(t,O(t)):a.set[e]&&(i=b(t,h)));var s;return g(n.caps,function(t){return g(n.aryMethod[t],function(r){if(e==r){var a=!p&&n.iterateeAry[e],o=n.iterateeRearg[e],l=n.methodSpread[e];return u.fixed&&(s=void 0===l?f(i,t):R(i,l)),u.rearg&&t>1&&(c||!n.skipRearg[e])&&(s=v(s,n.methodRearg[e]||n.aryRearg[t])), -u.cap&&(o?s=B(s,o):a&&(s=E(s,a))),u.curry&&t>1&&(s=d(s,t)),!1}}),!s}),s||(s=t),n.placeholder[e]&&(t.placeholder=s.placeholder=o),s};if(!p)return A(t,r);l.placeholder=o;var w=[];return g(n.caps,function(e){g(n.aryMethod[e],function(e){var t=l[n.rename[e]||e];t&&w.push([e,A(e,t)])})}),g(w,function(e){l[e[0]]=e[1]}),g(m(l),function(e){g(n.realToAlias[e]||[],function(t){l[t]=l[e]})}),l}var n=r(2),a=n.mutate,o={};e.exports=i},function(e,t){t.aliasToReal={__:"placeholder",all:"some",allPass:"overEvery", -apply:"spread",assoc:"set",assocPath:"set",compose:"flowRight",contains:"includes",dissoc:"unset",dissocPath:"unset",each:"forEach",eachRight:"forEachRight",equals:"isEqual",extend:"assignIn",extendWith:"assignInWith",first:"head",init:"initial",mapObj:"mapValues",omitAll:"omit",nAry:"ary",path:"get",pathEq:"matchesProperty",pathOr:"getOr",pickAll:"pick",pipe:"flow",prop:"get",propOf:"propertyOf",propOr:"getOr",somePass:"overSome",unapply:"rest",unnest:"flatten",useWith:"overArgs",whereEq:"filter", -zipObj:"zipObject"},t.aryMethod={1:["attempt","ceil","create","curry","curryRight","floor","fromPairs","invert","iteratee","memoize","method","methodOf","mixin","over","overEvery","overSome","rest","reverse","round","runInContext","spread","template","trim","trimEnd","trimStart","uniqueId","words"],2:["add","after","ary","assign","assignIn","at","before","bind","bindKey","chunk","cloneDeepWith","cloneWith","concat","countBy","curryN","curryRightN","debounce","defaults","defaultsDeep","delay","difference","drop","dropRight","dropRightWhile","dropWhile","endsWith","eq","every","filter","find","find","findIndex","findKey","findLast","findLastIndex","findLastKey","flatMap","forEach","forEachRight","forIn","forInRight","forOwn","forOwnRight","get","groupBy","gt","gte","has","hasIn","includes","indexOf","intersection","invertBy","invoke","invokeMap","isEqual","isMatch","join","keyBy","lastIndexOf","lt","lte","map","mapKeys","mapValues","matchesProperty","maxBy","merge","minBy","omit","omitBy","orderBy","overArgs","pad","padEnd","padStart","parseInt","partial","partialRight","partition","pick","pickBy","pull","pullAll","pullAt","random","range","rangeRight","rearg","reject","remove","repeat","result","sampleSize","some","sortBy","sortedIndex","sortedIndexOf","sortedLastIndex","sortedLastIndexOf","sortedUniqBy","split","startsWith","subtract","sumBy","take","takeRight","takeRightWhile","takeWhile","tap","throttle","thru","times","trimChars","trimCharsEnd","trimCharsStart","truncate","union","uniqBy","uniqWith","unset","unzipWith","without","wrap","xor","zip","zipObject","zipObjectDeep"], -3:["assignInWith","assignWith","clamp","differenceBy","differenceWith","getOr","inRange","intersectionBy","intersectionWith","isEqualWith","isMatchWith","mergeWith","pullAllBy","reduce","reduceRight","replace","set","slice","sortedIndexBy","sortedLastIndexBy","transform","unionBy","unionWith","xorBy","xorWith","zipWith"],4:["fill","setWith"]},t.aryRearg={2:[1,0],3:[2,1,0],4:[3,2,0,1]},t.caps=[1,2,3,4],t.iterateeAry={assignWith:2,assignInWith:2,cloneDeepWith:1,cloneWith:1,dropRightWhile:1,dropWhile:1, -every:1,filter:1,find:1,findIndex:1,findKey:1,findLast:1,findLastIndex:1,findLastKey:1,flatMap:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,isEqualWith:2,isMatchWith:2,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},t.iterateeRearg={findKey:[1],findLastKey:[1],mapKeys:[1]},t.methodRearg={assignInWith:[1,2,0],assignWith:[1,2,0],clamp:[2,0,1],mergeWith:[1,2,0],reduce:[2,0,1],reduceRight:[2,0,1], -set:[2,0,1],setWith:[3,1,2,0],slice:[2,0,1],transform:[2,0,1]},t.methodSpread={partial:1,partialRight:1},t.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignIn:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsDeep:!0,merge:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0}},t.placeholder={bind:!0,bindKey:!0,curry:!0,curryRight:!0,partial:!0,partialRight:!0},t.realToAlias=function(){var e=Object.prototype.hasOwnProperty,r=t.aliasToReal,i={}; -for(var n in r){var a=r[n];e.call(i,a)?i[a].push(n):i[a]=[n]}return i}(),t.rename={curryN:"curry",curryRightN:"curryRight",getOr:"get",trimChars:"trim",trimCharsEnd:"trimEnd",trimCharsStart:"trimStart"},t.skipRearg={add:!0,assign:!0,assignIn:!0,concat:!0,difference:!0,gt:!0,gte:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,partial:!0,partialRight:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,zip:!0,zipObject:!0}}])}); \ No newline at end of file +!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.fp=r():e.fp=r()}(this,function(){return function(e){function r(i){if(t[i])return t[i].exports;var n=t[i]={exports:{},id:i,loaded:!1};return e[i].call(n.exports,n,n.exports,r),n.loaded=!0,n.exports}var t={};return r.m=e,r.c=t,r.p="",r(0)}([function(e,r,t){function i(e,r){return n(e,e,r)}var n=t(1);"function"==typeof _&&(_=i(_.runInContext())), +e.exports=i},function(e,r,t){function i(e,r,t,s){var u,c="function"==typeof r,p=r===Object(r);if(p&&(s=t,t=r,r=void 0),null==t)throw new TypeError;s||(s={});var l={cap:"cap"in s?s.cap:!0,curry:"curry"in s?s.curry:!0,fixed:"fixed"in s?s.fixed:!0,immutable:"immutable"in s?s.immutable:!0,rearg:"rearg"in s?s.rearg:!0},f="rearg"in s&&s.rearg,h=c?t:{ary:e.ary,cloneDeep:e.cloneDeep,curry:e.curry,forEach:e.forEach,isArray:e.isArray,isFunction:e.isFunction,iteratee:e.iteratee,keys:e.keys,rearg:e.rearg,spread:e.spread +},d=h.ary,y=h.cloneDeep,g=h.curry,m=h.forEach,v=h.isArray,W=h.isFunction,x=h.keys,R=h.rearg,I=h.spread,O=x(n.aryMethod),b=function(e,r){return 2==r?function(r,t){return e(r,t)}:function(r){return e(r)}},A=function(e){for(var r=e?e.length:0,t=Array(r);r--;)t[r]=e[r];return t},B=function(e){return function(r){return e({},r)}},E=function(e,r){return function(){var t=arguments.length;if(!t)return n;for(var i=Array(t);t--;)i[t]=arguments[t];var n=i[0]=r(i[0]);return e.apply(void 0,i),n}},k=function(e,r){ +return j(e,function(e){return b(e,r)})},j=function(e,r,t){return function(){var t=arguments.length;if(!t)return e();for(var i=Array(t);t--;)i[t]=arguments[t];var n=l.rearg?0:t-1;return i[n]=r(i[n]),e.apply(void 0,i)}},w={castArray:function(e){return function(){var r=arguments[0];return v(r)?e(A(r)):e.apply(void 0,arguments)}},iteratee:function(e){return function(){var r=arguments[0],t=arguments[1];if(!l.cap)return e(r,t);t=t>2?t-2:1,r=e(r);var i=r.length;return i&&t>=i?r:b(r,t)}},mixin:function(e){ +return function(r){var t=this;if(!W(t))return e(t,Object(r));var i=[],n=[];return m(x(r),function(e){var a=r[e];W(a)&&(n.push(e),i.push(t.prototype[e]))}),e(t,Object(r)),m(n,function(e,r){var n=i[r];W(n)?t.prototype[e]=n:delete t.prototype[e]}),t}},runInContext:function(r){return function(t){return i(e,r(t),s)}}},q=function(e,r){e=n.aliasToReal[e]||e;var t=w[e];if(t)return t(r);var i=r;l.immutable&&(a.array[e]?i=E(r,A):a.object[e]?i=E(r,B(r)):a.set[e]&&(i=E(r,y)));var s;return m(O,function(r){return m(n.aryMethod[r],function(t){ +if(e==t){var a=!c&&n.iterateeAry[e],o=n.methodSpread[e];return s=i,l.fixed&&(s=void 0===o?d(s,r):I(s,o)),l.rearg&&r>1&&(f||!n.skipRearg[e])&&(s=R(s,n.methodRearg[e]||n.aryRearg[r])),l.cap&&a&&(s=k(s,a)),l.curry&&r>1&&(s=g(s,r)),!1}}),!s}),s||(s=i),n.placeholder[e]&&(u=!0,r.placeholder=s.placeholder=o),s};if(!p)return q(r,t);var z=t,M=[];return m(O,function(e){m(n.aryMethod[e],function(e){var r=z[n.remap[e]||e];r&&M.push([e,q(e,r)])})}),m(M,function(e){z[e[0]]=e[1]}),u&&(z.placeholder=o),m(x(z),function(e){ +m(n.realToAlias[e]||[],function(r){z[r]=z[e]})}),z}var n=t(2),a=n.mutate,o={};e.exports=i},function(e,r){r.aliasToReal={__:"placeholder",all:"some",allPass:"overEvery",apply:"spread",assoc:"set",assocPath:"set",compose:"flowRight",contains:"includes",dissoc:"unset",dissocPath:"unset",each:"forEach",eachRight:"forEachRight",equals:"isEqual",extend:"assignIn",extendWith:"assignInWith",first:"head",init:"initial",mapObj:"mapValues",omitAll:"omit",nAry:"ary",path:"get",pathEq:"matchesProperty",pathOr:"getOr", +pickAll:"pick",pipe:"flow",prop:"get",propOf:"propertyOf",propOr:"getOr",somePass:"overSome",unapply:"rest",unnest:"flatten",useWith:"overArgs",whereEq:"filter",zipObj:"zipObject"},r.aryMethod={1:["attempt","castArray","ceil","create","curry","curryRight","floor","fromPairs","invert","iteratee","memoize","method","methodOf","mixin","over","overEvery","overSome","rest","reverse","round","runInContext","spread","template","trim","trimEnd","trimStart","uniqueId","words"],2:["add","after","ary","assign","assignIn","at","before","bind","bindKey","chunk","cloneDeepWith","cloneWith","concat","countBy","curryN","curryRightN","debounce","defaults","defaultsDeep","delay","difference","drop","dropRight","dropRightWhile","dropWhile","endsWith","eq","every","filter","find","find","findIndex","findKey","findLast","findLastIndex","findLastKey","flatMap","flattenDepth","forEach","forEachRight","forIn","forInRight","forOwn","forOwnRight","get","groupBy","gt","gte","has","hasIn","includes","indexOf","intersection","invertBy","invoke","invokeMap","isEqual","isMatch","join","keyBy","lastIndexOf","lt","lte","map","mapKeys","mapValues","matchesProperty","maxBy","merge","minBy","omit","omitBy","orderBy","overArgs","pad","padEnd","padStart","parseInt","partial","partialRight","partition","pick","pickBy","pull","pullAll","pullAt","random","range","rangeRight","rearg","reject","remove","repeat","result","sampleSize","some","sortBy","sortedIndex","sortedIndexOf","sortedLastIndex","sortedLastIndexOf","sortedUniqBy","split","startsWith","subtract","sumBy","take","takeRight","takeRightWhile","takeWhile","tap","throttle","thru","times","trimChars","trimCharsEnd","trimCharsStart","truncate","union","uniqBy","uniqWith","unset","unzipWith","without","wrap","xor","zip","zipObject","zipObjectDeep"], +3:["assignInWith","assignWith","clamp","differenceBy","differenceWith","getOr","inRange","intersectionBy","intersectionWith","isEqualWith","isMatchWith","mergeWith","pullAllBy","reduce","reduceRight","replace","set","slice","sortedIndexBy","sortedLastIndexBy","transform","unionBy","unionWith","xorBy","xorWith","zipWith"],4:["fill","setWith"]},r.aryRearg={2:[1,0],3:[2,0,1],4:[3,2,0,1]},r.iterateeAry={assignWith:2,assignInWith:2,cloneDeepWith:1,cloneWith:1,dropRightWhile:1,dropWhile:1,every:1,filter:1, +find:1,findIndex:1,findKey:1,findLast:1,findLastIndex:1,findLastKey:1,flatMap:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,isEqualWith:2,isMatchWith:2,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},r.methodRearg={assignInWith:[1,2,0],assignWith:[1,2,0],getOr:[2,1,0],isMatchWith:[2,1,0],mergeWith:[1,2,0],pullAllBy:[2,1,0],setWith:[3,1,2,0],sortedIndexBy:[2,1,0],sortedLastIndexBy:[2,1,0], +zipWith:[1,2,0]},r.methodSpread={partial:1,partialRight:1},r.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignIn:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsDeep:!0,merge:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0}},r.placeholder={bind:!0,bindKey:!0,curry:!0,curryRight:!0,partial:!0,partialRight:!0},r.realToAlias=function(){var e=Object.prototype.hasOwnProperty,t=r.aliasToReal,i={};for(var n in t){var a=t[n];e.call(i,a)?i[a].push(n):i[a]=[n]; +}return i}(),r.remap={curryN:"curry",curryRightN:"curryRight",getOr:"get",trimChars:"trim",trimCharsEnd:"trimEnd",trimCharsStart:"trimStart"},r.skipRearg={add:!0,assign:!0,assignIn:!0,concat:!0,difference:!0,gt:!0,gte:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,partial:!0,partialRight:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,zip:!0,zipObject:!0}}])}); \ No newline at end of file diff --git a/dist/lodash.js b/dist/lodash.js index 125e3422b5..c3db53e182 100644 --- a/dist/lodash.js +++ b/dist/lodash.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.3.0 (Custom Build) + * lodash 4.4.0 (Custom Build) * Build: `lodash -o ./dist/lodash.js` * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -13,7 +13,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '4.3.0'; + var VERSION = '4.4.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, @@ -335,10 +335,19 @@ freeParseInt = parseInt; /** Detect free variable `exports`. */ - var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : null; + var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) + ? exports + : undefined; /** Detect free variable `module`. */ - var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : null; + var freeModule = (objectTypes[typeof module] && module && !module.nodeType) + ? module + : undefined; + + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = (freeModule && freeModule.exports === freeExports) + ? freeExports + : undefined; /** Detect free variable `global` from Node.js. */ var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global); @@ -349,9 +358,6 @@ /** Detect free variable `window`. */ var freeWindow = checkGlobal(objectTypes[typeof window] && window); - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports : null; - /** Detect `this` as the global object. */ var thisGlobal = checkGlobal(objectTypes[typeof this] && this); @@ -361,7 +367,9 @@ * The `this` value is used if it's the global object to avoid Greasemonkey's * restricted `window` object, otherwise the `window` object is used. */ - var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')(); + var root = freeGlobal || + ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || + freeSelf || thisGlobal || Function('return this')(); /*--------------------------------------------------------------------------*/ @@ -1316,6 +1324,7 @@ getPrototypeOf = Object.getPrototypeOf, getOwnPropertySymbols = Object.getOwnPropertySymbols, iteratorSymbol = typeof (iteratorSymbol = Symbol && Symbol.iterator) == 'symbol' ? iteratorSymbol : undefined, + objectCreate = Object.create, propertyIsEnumerable = objectProto.propertyIsEnumerable, setTimeout = context.setTimeout, splice = arrayProto.splice; @@ -1395,28 +1404,28 @@ * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, - * `at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`, - * `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`, - * `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, + * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, + * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, + * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, + * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, * `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, - * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`, - * `flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, - * `intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, - * `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, - * `mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, - * `method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, - * `orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`, - * `partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`, - * `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, - * `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, - * `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, - * `thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, - * `transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, - * `uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, - * `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, - * `zipObjectDeep`, and `zipWith` + * `dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, + * `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, + * `groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, + * `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, + * `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, + * `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, + * `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, + * `overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`, + * `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, + * `range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, + * `splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, + * `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, + * `toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, + * `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`, + * `unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, + * `xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, @@ -1510,7 +1519,7 @@ * * @static * @memberOf _ - * @type Object + * @type {Object} */ lodash.templateSettings = { @@ -1518,7 +1527,7 @@ * Used to detect `data` property values to be HTML-escaped. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'escape': reEscape, @@ -1526,7 +1535,7 @@ * Used to detect code to be evaluated. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'evaluate': reEvaluate, @@ -1534,7 +1543,7 @@ * Used to detect `data` property values to inject. * * @memberOf _.templateSettings - * @type RegExp + * @type {RegExp} */ 'interpolate': reInterpolate, @@ -1542,7 +1551,7 @@ * Used to reference the data object in the template text. * * @memberOf _.templateSettings - * @type string + * @type {string} */ 'variable': '', @@ -1550,7 +1559,7 @@ * Used to import variables into the compiled template. * * @memberOf _.templateSettings - * @type Object + * @type {Object} */ 'imports': { @@ -1558,7 +1567,7 @@ * A reference to the `lodash` function. * * @memberOf _.templateSettings.imports - * @type Function + * @type {Function} */ '_': lodash } @@ -1570,6 +1579,7 @@ * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. * * @private + * @constructor * @param {*} value The value to wrap. */ function LazyWrapper(value) { @@ -1645,7 +1655,8 @@ resIndex = 0, takeCount = nativeMin(length, this.__takeCount__); - if (!isArr || arrLength < LARGE_ARRAY_SIZE || (arrLength == length && takeCount == length)) { + if (!isArr || arrLength < LARGE_ARRAY_SIZE || + (arrLength == length && takeCount == length)) { return baseWrapperValue(array, this.__actions__); } var result = []; @@ -1684,6 +1695,7 @@ * Creates an hash object. * * @private + * @constructor * @returns {Object} Returns the new hash object. */ function Hash() {} @@ -1746,6 +1758,7 @@ * Creates a map cache object to store key-value pairs. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function MapCache(values) { @@ -1767,7 +1780,11 @@ * @memberOf MapCache */ function mapClear() { - this.__data__ = { 'hash': new Hash, 'map': Map ? new Map : [], 'string': new Hash }; + this.__data__ = { + 'hash': new Hash, + 'map': Map ? new Map : [], + 'string': new Hash + }; } /** @@ -1850,6 +1867,7 @@ * Creates a set cache object to store unique values. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { @@ -1908,6 +1926,7 @@ * Creates a stack cache object to store key-value pairs. * * @private + * @constructor * @param {Array} [values] The values to cache. */ function Stack(values) { @@ -2199,6 +2218,39 @@ return result; } + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + + /** + * Casts `value` to `identity` if it's not a function. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastFunction(value) { + return typeof value == 'function' ? value : identity; + } + + /** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ + function baseCastPath(value) { + return isArray(value) ? value : stringToPath(value); + } + /** * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. * @@ -2323,17 +2375,9 @@ * @param {Object} prototype The object to inherit from. * @returns {Object} Returns the new object. */ - var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; - }; - }()); + function baseCreate(proto) { + return isObject(proto) ? objectCreate(proto) : {}; + } /** * The base implementation of `_.delay` and `_.defer` which accepts an array @@ -2495,12 +2539,12 @@ * * @private * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. + * @param {number} depth The maximum recursion depth. * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ - function baseFlatten(array, isDeep, isStrict, result) { + function baseFlatten(array, depth, isStrict, result) { result || (result = []); var index = -1, @@ -2508,11 +2552,11 @@ while (++index < length) { var value = array[index]; - if (isArrayLikeObject(value) && + if (depth > 0 && isArrayLikeObject(value) && (isStrict || isArray(value) || isArguments(value))) { - if (isDeep) { + if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, isDeep, isStrict, result); + baseFlatten(value, depth - 1, isStrict, result); } else { arrayPush(result, value); } @@ -2609,7 +2653,7 @@ * @returns {*} Returns the resolved value. */ function baseGet(object, path) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : baseCastPath(path); var index = 0, length = path.length; @@ -2698,11 +2742,17 @@ var value = array[index], computed = iteratee ? iteratee(value) : value; - if (!(seen ? cacheHas(seen, computed) : includes(result, computed, comparator))) { + if (!(seen + ? cacheHas(seen, computed) + : includes(result, computed, comparator) + )) { var othIndex = othLength; while (--othIndex) { var cache = caches[othIndex]; - if (!(cache ? cacheHas(cache, computed) : includes(arrays[othIndex], computed, comparator))) { + if (!(cache + ? cacheHas(cache, computed) + : includes(arrays[othIndex], computed, comparator)) + ) { continue outer; } } @@ -2745,7 +2795,7 @@ */ function baseInvoke(object, path, args) { if (!isKey(path, object)) { - path = baseToPath(path); + path = baseCastPath(path); object = parent(object, path); path = last(path); } @@ -2918,7 +2968,6 @@ * property of prototypes or treat sparse arrays as dense. * * @private - * @type Function * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ @@ -3026,7 +3075,10 @@ if (object === source) { return; } - var props = (isArray(source) || isTypedArray(source)) ? undefined : keysIn(source); + var props = (isArray(source) || isTypedArray(source)) + ? undefined + : keysIn(source); + arrayEach(props || source, function(srcValue, key) { if (props) { key = srcValue; @@ -3037,7 +3089,10 @@ baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); } else { - var newValue = customizer ? customizer(object[key], srcValue, (key + ''), object, source, stack) : undefined; + var newValue = customizer + ? customizer(object[key], srcValue, (key + ''), object, source, stack) + : undefined; + if (newValue === undefined) { newValue = srcValue; } @@ -3069,21 +3124,24 @@ assignMergeValue(object, key, stacked); return; } - var newValue = customizer ? customizer(objValue, srcValue, (key + ''), object, source, stack) : undefined, - isCommon = newValue === undefined; + var newValue = customizer + ? customizer(objValue, srcValue, (key + ''), object, source, stack) + : undefined; + + var isCommon = newValue === undefined; if (isCommon) { newValue = srcValue; if (isArray(srcValue) || isTypedArray(srcValue)) { if (isArray(objValue)) { - newValue = srcIndex ? copyArray(objValue) : objValue; + newValue = objValue; } else if (isArrayLikeObject(objValue)) { newValue = copyArray(objValue); } else { isCommon = false; - newValue = baseClone(srcValue); + newValue = baseClone(srcValue, true); } } else if (isPlainObject(srcValue) || isArguments(srcValue)) { @@ -3092,10 +3150,10 @@ } else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { isCommon = false; - newValue = baseClone(srcValue); + newValue = baseClone(srcValue, true); } else { - newValue = srcIndex ? baseClone(objValue) : objValue; + newValue = objValue; } } else { @@ -3269,7 +3327,7 @@ splice.call(array, index, 1); } else if (!isKey(index, array)) { - var path = baseToPath(index), + var path = baseCastPath(index), object = parent(array, path); if (object != null) { @@ -3331,7 +3389,7 @@ * @returns {Object} Returns `object`. */ function baseSet(object, path, value, customizer) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : baseCastPath(path); var index = -1, length = path.length, @@ -3346,7 +3404,9 @@ var objValue = nested[key]; newValue = customizer ? customizer(objValue, key, nested) : undefined; if (newValue === undefined) { - newValue = objValue == null ? (isIndex(path[index + 1]) ? [] : {}) : objValue; + newValue = objValue == null + ? (isIndex(path[index + 1]) ? [] : {}) + : objValue; } } assignValue(nested, key, newValue); @@ -3537,18 +3597,6 @@ return result; } - /** - * The base implementation of `_.toPath` which only converts `value` to a - * path if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the property path array. - */ - function baseToPath(value) { - return isArray(value) ? value : stringToPath(value); - } - /** * The base implementation of `_.uniqBy` without support for iteratee shorthands. * @@ -3618,7 +3666,7 @@ * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ function baseUnset(object, path) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : baseCastPath(path); object = parent(object, path); var key = last(path); return (object != null && has(object, key)) ? delete object[key] : true; @@ -3807,10 +3855,11 @@ * @returns {Object} Returns the cloned typed array. */ function cloneTypedArray(typedArray, isDeep) { - var buffer = typedArray.buffer, + var arrayBuffer = typedArray.buffer, + buffer = isDeep ? cloneArrayBuffer(arrayBuffer) : arrayBuffer, Ctor = typedArray.constructor; - return new Ctor(isDeep ? cloneArrayBuffer(buffer) : buffer, typedArray.byteOffset, typedArray.length); + return new Ctor(buffer, typedArray.byteOffset, typedArray.length); } /** @@ -3925,8 +3974,11 @@ length = props.length; while (++index < length) { - var key = props[index], - newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key]; + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; assignValue(object, key, newValue); } @@ -3976,7 +4028,10 @@ customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; - customizer = typeof customizer == 'function' ? (length--, customizer) : undefined; + customizer = typeof customizer == 'function' + ? (length--, customizer) + : undefined; + if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; @@ -4077,8 +4132,11 @@ return function(string) { string = toString(string); - var strSymbols = reHasComplexSymbol.test(string) ? stringToArray(string) : undefined, - chr = strSymbols ? strSymbols[0] : string.charAt(0), + var strSymbols = reHasComplexSymbol.test(string) + ? stringToArray(string) + : undefined; + + var chr = strSymbols ? strSymbols[0] : string.charAt(0), trailing = strSymbols ? strSymbols.slice(1).join('') : string.slice(1); return chr[methodName]() + trailing; @@ -4174,7 +4232,7 @@ */ function createFlow(fromRight) { return rest(function(funcs) { - funcs = baseFlatten(funcs); + funcs = baseFlatten(funcs, 1); var length = funcs.length, index = length, @@ -4199,7 +4257,10 @@ var funcName = getFuncName(func), data = funcName == 'wrapper' ? getData(func) : undefined; - if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + if (data && isLaziable(data[0]) && + data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && + !data[4].length && data[9] == 1 + ) { wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); } else { wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); @@ -4209,7 +4270,8 @@ var args = arguments, value = args[0]; - if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { + if (wrapper && args.length == 1 && + isArray(value) && value.length >= LARGE_ARRAY_SIZE) { return wrapper.plant(value).value(); } var index = 0, @@ -4269,7 +4331,10 @@ length -= argsHolders.length; if (length < arity) { - return createRecurryWrapper(func, bitmask, createHybridWrapper, placeholder, thisArg, args, argsHolders, argPos, ary, arity - length); + return createRecurryWrapper( + func, bitmask, createHybridWrapper, placeholder, thisArg, args, + argsHolders, argPos, ary, arity - length + ); } } var thisBinding = isBind ? thisArg : this, @@ -4314,7 +4379,7 @@ */ function createOver(arrayFunc) { return rest(function(iteratees) { - iteratees = arrayMap(baseFlatten(iteratees), getIteratee()); + iteratees = arrayMap(baseFlatten(iteratees, 1), getIteratee()); return rest(function(args) { var thisArg = this; return arrayFunc(iteratees, function(iteratee) { @@ -4441,9 +4506,12 @@ if (!(bitmask & CURRY_BOUND_FLAG)) { bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); } - var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, arity], - result = wrapFunc.apply(undefined, newData); + var newData = [ + func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, + newHoldersRight, newArgPos, ary, arity + ]; + var result = wrapFunc.apply(undefined, newData); if (isLaziable(func)) { setData(result, newData); } @@ -4532,8 +4600,12 @@ partials = holders = undefined; } - var data = isBindKey ? undefined : getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; + var data = isBindKey ? undefined : getData(func); + + var newData = [ + func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, + argPos, ary, arity + ]; if (data) { mergeData(newData, data); @@ -4941,7 +5013,7 @@ } var result = hasFunc(object, path); if (!result && !isKey(path)) { - path = baseToPath(path); + path = baseCastPath(path); object = parent(object, path); if (object != null) { path = last(path); @@ -5100,7 +5172,7 @@ function isKeyable(value) { var type = typeof value; return type == 'number' || type == 'boolean' || - (type == 'string' && value !== '__proto__') || value == null; + (type == 'string' && value != '__proto__') || value == null; } /** @@ -5322,28 +5394,6 @@ return result; } - /** - * Converts `value` to an array-like object if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the array-like object. - */ - function toArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Converts `value` to a function if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Function} Returns the function. - */ - function toFunction(value) { - return typeof value == 'function' ? value : identity; - } - /** * Creates a clone of `wrapper`. * @@ -5454,7 +5504,7 @@ if (!isArray(array)) { array = array == null ? [] : [Object(array)]; } - values = baseFlatten(values); + values = baseFlatten(values, 1); return arrayConcat(array, values); }); @@ -5476,7 +5526,7 @@ */ var difference = rest(function(array, values) { return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, false, true)) + ? baseDifference(array, baseFlatten(values, 1, true)) : []; }); @@ -5507,7 +5557,7 @@ iteratee = undefined; } return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, false, true), getIteratee(iteratee)) + ? baseDifference(array, baseFlatten(values, 1, true), getIteratee(iteratee)) : []; }); @@ -5536,7 +5586,7 @@ comparator = undefined; } return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, false, true), undefined, comparator) + ? baseDifference(array, baseFlatten(values, 1, true), undefined, comparator) : []; }); @@ -5806,7 +5856,7 @@ } /** - * Flattens `array` a single level. + * Flattens `array` a single level deep. * * @static * @memberOf _ @@ -5815,30 +5865,58 @@ * @returns {Array} Returns the new flattened array. * @example * - * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]] + * _.flatten([1, [2, [3, [4]], 5]]); + * // => [1, 2, [3, [4]], 5] */ function flatten(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array) : []; + return length ? baseFlatten(array, 1) : []; } /** - * This method is like `_.flatten` except that it recursively flattens `array`. + * Recursively flattens `array`. * * @static * @memberOf _ * @category Array - * @param {Array} array The array to recursively flatten. + * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] + * _.flattenDeep([1, [2, [3, [4]], 5]]); + * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; + return length ? baseFlatten(array, INFINITY) : []; + } + + /** + * Recursively flatten `array` up to `depth` times. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {number} [depth=1] The maximum recursion depth. + * @returns {Array} Returns the new flattened array. + * @example + * + * var array = [1, [2, [3, [4]], 5]]; + * + * _.flattenDepth(array, 1); + * // => [1, 2, [3, [4]], 5] + * + * _.flattenDepth(array, 2); + * // => [1, 2, 3, [4], 5] + */ + function flattenDepth(array, depth) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + depth = depth === undefined ? 1 : toInteger(depth); + return baseFlatten(array, depth); } /** @@ -5955,7 +6033,7 @@ * // => [2] */ var intersection = rest(function(arrays) { - var mapped = arrayMap(arrays, toArrayLikeObject); + var mapped = arrayMap(arrays, baseCastArrayLikeObject); return (mapped.length && mapped[0] === arrays[0]) ? baseIntersection(mapped) : []; @@ -5983,7 +6061,7 @@ */ var intersectionBy = rest(function(arrays) { var iteratee = last(arrays), - mapped = arrayMap(arrays, toArrayLikeObject); + mapped = arrayMap(arrays, baseCastArrayLikeObject); if (iteratee === last(mapped)) { iteratee = undefined; @@ -6016,7 +6094,7 @@ */ var intersectionWith = rest(function(arrays) { var comparator = last(arrays), - mapped = arrayMap(arrays, toArrayLikeObject); + mapped = arrayMap(arrays, baseCastArrayLikeObject); if (comparator === last(mapped)) { comparator = undefined; @@ -6206,7 +6284,7 @@ * // => [10, 20] */ var pullAt = rest(function(array, indexes) { - indexes = arrayMap(baseFlatten(indexes), String); + indexes = arrayMap(baseFlatten(indexes, 1), String); var result = baseAt(array, indexes); basePullAt(array, indexes.sort(compareAscending)); @@ -6678,7 +6756,7 @@ * // => [2, 1, 4] */ var union = rest(function(arrays) { - return baseUniq(baseFlatten(arrays, false, true)); + return baseUniq(baseFlatten(arrays, 1, true)); }); /** @@ -6706,7 +6784,7 @@ if (isArrayLikeObject(iteratee)) { iteratee = undefined; } - return baseUniq(baseFlatten(arrays, false, true), getIteratee(iteratee)); + return baseUniq(baseFlatten(arrays, 1, true), getIteratee(iteratee)); }); /** @@ -6733,7 +6811,7 @@ if (isArrayLikeObject(comparator)) { comparator = undefined; } - return baseUniq(baseFlatten(arrays, false, true), undefined, comparator); + return baseUniq(baseFlatten(arrays, 1, true), undefined, comparator); }); /** @@ -7157,17 +7235,22 @@ * // => ['a', 'c'] */ var wrapperAt = rest(function(paths) { - paths = baseFlatten(paths); + paths = baseFlatten(paths, 1); var length = paths.length, start = length ? paths[0] : 0, value = this.__wrapped__, interceptor = function(object) { return baseAt(object, paths); }; - if (length > 1 || this.__actions__.length || !(value instanceof LazyWrapper) || !isIndex(start)) { + if (length > 1 || this.__actions__.length || + !(value instanceof LazyWrapper) || !isIndex(start)) { return this.thru(interceptor); } value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); + value.__actions__.push({ + 'func': thru, + 'args': [interceptor], + 'thisArg': undefined + }); return new LodashWrapper(value, this.__chain__).thru(function(array) { if (length && !array.length) { array.push(undefined); @@ -7378,7 +7461,11 @@ wrapped = new LazyWrapper(this); } wrapped = wrapped.reverse(); - wrapped.__actions__.push({ 'func': thru, 'args': [reverse], 'thisArg': undefined }); + wrapped.__actions__.push({ + 'func': thru, + 'args': [reverse], + 'thisArg': undefined + }); return new LodashWrapper(wrapped, this.__chain__); } return this.thru(reverse); @@ -7597,7 +7684,7 @@ * // => [1, 1, 2, 2] */ function flatMap(collection, iteratee) { - return baseFlatten(map(collection, iteratee)); + return baseFlatten(map(collection, iteratee), 1); } /** @@ -7631,7 +7718,7 @@ function forEach(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEach(collection, iteratee) - : baseEach(collection, toFunction(iteratee)); + : baseEach(collection, baseCastFunction(iteratee)); } /** @@ -7655,7 +7742,7 @@ function forEachRight(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, toFunction(iteratee)); + : baseEachRight(collection, baseCastFunction(iteratee)); } /** @@ -8219,7 +8306,7 @@ } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { iteratees.length = 1; } - return baseOrderBy(collection, baseFlatten(iteratees), []); + return baseOrderBy(collection, baseFlatten(iteratees, 1), []); }); /*------------------------------------------------------------------------*/ @@ -8230,7 +8317,7 @@ * * @static * @memberOf _ - * @type Function + * @type {Function} * @category Date * @returns {number} Returns the timestamp. * @example @@ -8656,8 +8743,10 @@ if (!lastCalled && !maxTimeoutId && !leading) { lastCalled = stamp; } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0 || remaining > maxWait; + var remaining = maxWait - (stamp - lastCalled); + + var isCalled = (remaining <= 0 || remaining > maxWait) && + (leading || maxTimeoutId); if (isCalled) { if (maxTimeoutId) { @@ -8897,7 +8986,7 @@ * // => [100, 10] */ var overArgs = rest(function(func, transforms) { - transforms = arrayMap(baseFlatten(transforms), getIteratee()); + transforms = arrayMap(baseFlatten(transforms, 1), getIteratee()); var funcsLength = transforms.length; return rest(function(args) { @@ -9011,7 +9100,7 @@ * // => ['a', 'b', 'c'] */ var rearg = rest(function(func, indexes) { - return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); + return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); }); /** @@ -9163,7 +9252,11 @@ leading = 'leading' in options ? !!options.leading : leading; trailing = 'trailing' in options ? !!options.trailing : trailing; } - return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing }); + return debounce(func, wait, { + 'leading': leading, + 'maxWait': wait, + 'trailing': trailing + }); } /** @@ -9194,7 +9287,7 @@ * @memberOf _ * @category Function * @param {*} value The value to wrap. - * @param {Function} wrapper The wrapper function. + * @param {Function} [wrapper=identity] The wrapper function. * @returns {Function} Returns the new function. * @example * @@ -9212,6 +9305,46 @@ /*------------------------------------------------------------------------*/ + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + /** * Creates a shallow clone of `value`. * @@ -9432,7 +9565,7 @@ * * @static * @memberOf _ - * @type Function + * @type {Function} * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. @@ -9457,7 +9590,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. @@ -9480,7 +9612,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. @@ -9509,7 +9640,6 @@ * * @static * @memberOf _ - * @type Function * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, else `false`. @@ -9641,7 +9771,8 @@ */ function isEmpty(value) { if (isArrayLike(value) && - (isArray(value) || isString(value) || isFunction(value.splice) || isArguments(value))) { + (isArray(value) || isString(value) || + isFunction(value.splice) || isArguments(value))) { return !value.length; } for (var key in value) { @@ -9684,10 +9815,10 @@ } /** - * This method is like `_.isEqual` except that it accepts `customizer` which is - * invoked to compare values. If `customizer` returns `undefined` comparisons are - * handled by the method instead. The `customizer` is invoked with up to six arguments: - * (objValue, othValue [, index|key, object, other, stack]). + * This method is like `_.isEqual` except that it accepts `customizer` which + * is invoked to compare values. If `customizer` returns `undefined` comparisons + * are handled by the method instead. The `customizer` is invoked with up to + * six arguments: (objValue, othValue [, index|key, object, other, stack]). * * @static * @memberOf _ @@ -9738,8 +9869,12 @@ * // => false */ function isError(value) { - return isObjectLike(value) && - typeof value.message == 'string' && objectToString.call(value) == errorTag; + if (!isObjectLike(value)) { + return false; + } + var Ctor = value.constructor; + return (objectToString.call(value) == errorTag) || + (typeof Ctor == 'function' && objectToString.call(Ctor.prototype) == errorTag); } /** @@ -9847,7 +9982,8 @@ * // => false */ function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** @@ -9926,8 +10062,9 @@ } /** - * Performs a deep comparison between `object` and `source` to determine if - * `object` contains equivalent property values. + * Performs a partial deep comparison between `object` and `source` to + * determine if `object` contains equivalent property values. This method is + * equivalent to a `_.matches` function when `source` is partially applied. * * **Note:** This method supports comparing the same values as `_.isEqual`. * @@ -10146,7 +10283,8 @@ * // => true */ function isPlainObject(value) { - if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) { + if (!isObjectLike(value) || + objectToString.call(value) != objectTag || isHostObject(value)) { return false; } var proto = objectProto; @@ -10289,7 +10427,8 @@ * // => false */ function isTypedArray(value) { - return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; } /** @@ -10781,7 +10920,7 @@ * // => ['a', 'c'] */ var at = rest(function(object, paths) { - return baseAt(object, baseFlatten(paths)); + return baseAt(object, baseFlatten(paths, 1)); }); /** @@ -10969,7 +11108,9 @@ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) */ function forIn(object, iteratee) { - return object == null ? object : baseFor(object, toFunction(iteratee), keysIn); + return object == null + ? object + : baseFor(object, baseCastFunction(iteratee), keysIn); } /** @@ -10997,7 +11138,9 @@ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' */ function forInRight(object, iteratee) { - return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn); + return object == null + ? object + : baseForRight(object, baseCastFunction(iteratee), keysIn); } /** @@ -11027,7 +11170,7 @@ * // => logs 'a' then 'b' (iteration order is not guaranteed) */ function forOwn(object, iteratee) { - return object && baseForOwn(object, toFunction(iteratee)); + return object && baseForOwn(object, baseCastFunction(iteratee)); } /** @@ -11055,7 +11198,7 @@ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' */ function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, toFunction(iteratee)); + return object && baseForOwnRight(object, baseCastFunction(iteratee)); } /** @@ -11422,12 +11565,12 @@ } /** - * Recursively merges own and inherited enumerable properties of source - * objects into the destination object, skipping source properties that resolve - * to `undefined`. Array and plain object properties are merged recursively. - * Other objects and value types are overridden by assignment. Source objects - * are applied from left to right. Subsequent sources overwrite property - * assignments of previous sources. + * Recursively merges own and inherited enumerable properties of source objects + * into the destination object. Source properties that resolve to `undefined` + * are skipped if a destination value exists. Array and plain object properties + * are merged recursively. Other objects and value types are overridden by + * assignment. Source objects are applied from left to right. Subsequent + * sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object`. * @@ -11504,7 +11647,7 @@ * @category Object * @param {Object} object The source object. * @param {...(string|string[])} [props] The property names to omit, specified - * individually or in arrays.. + * individually or in arrays. * @returns {Object} Returns the new object. * @example * @@ -11517,7 +11660,7 @@ if (object == null) { return {}; } - props = arrayMap(baseFlatten(props), String); + props = arrayMap(baseFlatten(props, 1), String); return basePick(object, baseDifference(keysIn(object), props)); }); @@ -11564,7 +11707,7 @@ * // => { 'a': 1, 'c': 3 } */ var pick = rest(function(object, props) { - return object == null ? {} : basePick(object, baseFlatten(props)); + return object == null ? {} : basePick(object, baseFlatten(props, 1)); }); /** @@ -11618,7 +11761,7 @@ */ function result(object, path, defaultValue) { if (!isKey(path, object)) { - path = baseToPath(path); + path = baseCastPath(path); var result = get(object, path); object = parent(object, path); } else { @@ -11688,7 +11831,8 @@ } /** - * Creates an array of own enumerable key-value pairs for `object`. + * Creates an array of own enumerable key-value pairs for `object` which + * can be consumed by `_.fromPairs`. * * @static * @memberOf _ @@ -11712,7 +11856,8 @@ } /** - * Creates an array of own and inherited enumerable key-value pairs for `object`. + * Creates an array of own and inherited enumerable key-value pairs for + * `object` which can be consumed by `_.fromPairs`. * * @static * @memberOf _ @@ -11867,7 +12012,7 @@ * // => [1, 2, 3] (iteration order is not guaranteed) */ function valuesIn(object) { - return object == null ? baseValues(object, keysIn(object)) : []; + return object == null ? [] : baseValues(object, keysIn(object)); } /*------------------------------------------------------------------------*/ @@ -12365,7 +12510,7 @@ * @memberOf _ * @category String * @param {string} string The string to convert. - * @param {number} [radix] The radix to interpret `value` by. + * @param {number} [radix=10] The radix to interpret `value` by. * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`. * @returns {number} Returns the converted integer. * @example @@ -12737,7 +12882,8 @@ 'return __p\n}'; var result = attempt(function() { - return Function(importsKeys, sourceURL + 'return ' + source).apply(undefined, importsValues); + return Function(importsKeys, sourceURL + 'return ' + source) + .apply(undefined, importsValues); }); // Provide the compiled function's source by its `toString` method or @@ -12831,7 +12977,9 @@ var strSymbols = stringToArray(string), chrSymbols = stringToArray(chars); - return strSymbols.slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1).join(''); + return strSymbols + .slice(charsStartIndex(strSymbols, chrSymbols), charsEndIndex(strSymbols, chrSymbols) + 1) + .join(''); } /** @@ -12865,7 +13013,9 @@ return string; } var strSymbols = stringToArray(string); - return strSymbols.slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1).join(''); + return strSymbols + .slice(0, charsEndIndex(strSymbols, stringToArray(chars)) + 1) + .join(''); } /** @@ -12899,7 +13049,9 @@ return string; } var strSymbols = stringToArray(string); - return strSymbols.slice(charsStartIndex(strSymbols, stringToArray(chars))).join(''); + return strSymbols + .slice(charsStartIndex(strSymbols, stringToArray(chars))) + .join(''); } /** @@ -12911,7 +13063,7 @@ * @memberOf _ * @category String * @param {string} [string=''] The string to truncate. - * @param {Object} [options] The options object. + * @param {Object} [options=({})] The options object. * @param {number} [options.length=30] The maximum string length. * @param {string} [options.omission='...'] The string to indicate text is omitted. * @param {RegExp|string} [options.separator] The separator pattern to truncate to. @@ -13096,7 +13248,7 @@ try { return apply(func, undefined, args); } catch (e) { - return isObject(e) ? e : new Error(e); + return isError(e) ? e : new Error(e); } }); @@ -13127,7 +13279,7 @@ * // => logs 'clicked docs' when clicked */ var bindAll = rest(function(object, methodNames) { - arrayEach(baseFlatten(methodNames), function(key) { + arrayEach(baseFlatten(methodNames, 1), function(key) { object[key] = bind(object[key], object); }); return object; @@ -13295,7 +13447,8 @@ * Creates a function that invokes `func` with the arguments of the created * function. If `func` is a property name the created callback returns the * property value for a given element. If `func` is an object the created - * callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`. + * callback returns `true` for elements that contain the equivalent object + * properties, otherwise it returns `false`. * * @static * @memberOf _ @@ -13325,9 +13478,10 @@ } /** - * Creates a function that performs a deep partial comparison between a given + * Creates a function that performs a partial deep comparison between a given * object and `source`, returning `true` if the given object has equivalent - * property values, else `false`. + * property values, else `false`. The created function is equivalent to + * `_.isMatch` with a `source` partially applied. * * **Note:** This method supports comparing the same values as `_.isEqual`. * @@ -13351,7 +13505,7 @@ } /** - * Creates a function that performs a deep partial comparison between the + * Creates a function that performs a partial deep comparison between the * value at `path` of a given object to `srcValue`, returning `true` if the * object value is equivalent, else `false`. * @@ -13785,7 +13939,7 @@ var index = MAX_ARRAY_LENGTH, length = nativeMin(n, MAX_ARRAY_LENGTH); - iteratee = toFunction(iteratee); + iteratee = baseCastFunction(iteratee); n -= MAX_ARRAY_LENGTH; var result = baseTimes(length, iteratee); @@ -13830,7 +13984,7 @@ * @static * @memberOf _ * @category Util - * @param {string} [prefix] The value to prefix the ID with. + * @param {string} [prefix=''] The value to prefix the ID with. * @returns {string} Returns the unique ID. * @example * @@ -14181,6 +14335,7 @@ lodash.bind = bind; lodash.bindAll = bindAll; lodash.bindKey = bindKey; + lodash.castArray = castArray; lodash.chain = chain; lodash.chunk = chunk; lodash.compact = compact; @@ -14209,6 +14364,7 @@ lodash.flatMap = flatMap; lodash.flatten = flatten; lodash.flattenDeep = flattenDeep; + lodash.flattenDepth = flattenDepth; lodash.flip = flip; lodash.flow = flow; lodash.flowRight = flowRight; @@ -14483,7 +14639,7 @@ * * @static * @memberOf _ - * @type string + * @type {string} */ lodash.VERSION = VERSION; @@ -14505,7 +14661,10 @@ if (filtered) { result.__takeCount__ = nativeMin(n, result.__takeCount__); } else { - result.__views__.push({ 'size': nativeMin(n, MAX_ARRAY_LENGTH), 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') }); + result.__views__.push({ + 'size': nativeMin(n, MAX_ARRAY_LENGTH), + 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') + }); } return result; }; @@ -14522,7 +14681,10 @@ LazyWrapper.prototype[methodName] = function(iteratee) { var result = this.clone(); - result.__iteratees__.push({ 'iteratee': getIteratee(iteratee, 3), 'type': type }); + result.__iteratees__.push({ + 'iteratee': getIteratee(iteratee, 3), + 'type': type + }); result.__filtered__ = result.__filtered__ || isFilter; return result; }; @@ -14674,7 +14836,10 @@ } }); - realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ 'name': 'wrapper', 'func': undefined }]; + realNames[createHybridWrapper(undefined, BIND_KEY_FLAG).name] = [{ + 'name': 'wrapper', + 'func': undefined + }]; // Add functions to the lazy wrapper. LazyWrapper.prototype.clone = lazyClone; diff --git a/dist/lodash.min.js b/dist/lodash.min.js index 0472b5f2c9..212533bce0 100644 --- a/dist/lodash.min.js +++ b/dist/lodash.min.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.3.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + * lodash 4.4.0 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE * Build: `lodash -o ./dist/lodash.js` */ ;(function(){function n(n,t){return n.set(t[0],t[1]),n}function t(n,t){return n.add(t),n}function r(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function e(n,t,r,e){for(var u=-1,o=n.length;++ut&&!o||!u||r&&!i&&f||e&&f)return 1;if(t>n&&!r||!f||o&&!e&&u||i&&u)return-1}return 0}function S(n){return Un[n]}function R(n){return zn[n]}function W(n){return"\\"+$n[n]}function B(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t-1&&0==n%1&&(null==t?9007199254740991:t)>n}function z(n){for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}function M(n){var t=-1,r=Array(n.size);return n.forEach(function(n,e){r[++t]=[e,n]}),r}function L(n,t){for(var r=-1,e=n.length,u=-1,o=[];++rr?false:(r==n.length-1?n.pop():Ou.call(n,r,1),true)}function Zn(n,t){var r=qn(n,t);return 0>r?Z:n[r][1]}function qn(n,t){for(var r=n.length;r--;)if(se(n[r][0],t))return r;return-1}function Pn(n,t,r){var e=qn(n,t);0>e?n.push([t,r]):n[e][1]=r}function Tn(n,t,r,e){return n===Z||se(n,iu[r])&&!cu.call(e,r)?t:n}function Gn(n,t,r){(r!==Z&&!se(n[t],r)||typeof t=="number"&&r===Z&&!(t in n))&&(n[t]=r)}function Yn(n,t,r){var e=n[t];(!se(e,r)||se(e,iu[t])&&!cu.call(n,t)||r===Z&&!(t in n))&&(n[t]=r); -}function Hn(n,t,r,e){return Ju(n,function(n,u,o){t(e,n,r(n),o)}),e}function Qn(n,t){return n&&Ht(t,Fe(t),n)}function Xn(n,t){for(var r=-1,e=null==n,u=t.length,o=Array(u);++rr?r:n),t!==Z&&(n=t>n?t:n)),n}function tt(n,t,r,e,o,i){var f;if(r&&(f=o?r(n,e,o,i):r(n)),f!==Z)return f;if(!xe(n))return n;if(e=No(n)){if(f=Ir(n),!t)return Yt(n,f)}else{var c=kr(n),a="[object Function]"==c||"[object GeneratorFunction]"==c;if(Do(n))return Kt(n,t); -if("[object Object]"!=c&&"[object Arguments]"!=c&&(!a||o))return Cn[c]?Rr(n,c,t):o?n:{};if(C(n))return o?n:{};if(f=Sr(a?{}:n),!t)return Xt(n,Qn(f,n))}return i||(i=new $n),(o=i.get(n))?o:(i.set(n,f),(e?u:at)(n,function(e,u){Yn(f,u,tt(e,t,r,u,n,i))}),e?f:Xt(n,f))}function rt(n){var t=Fe(n),r=t.length;return function(e){if(null==e)return!r;for(var u=r;u--;){var o=t[u],i=n[o],f=e[o];if(f===Z&&!(o in Object(e))||!i(f))return false}return true}}function et(n,t,r){if(typeof n!="function")throw new uu("Expected a function"); -return Au(function(){n.apply(Z,r)},t)}function ut(n,t,r,e){var u=-1,o=f,i=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=a(t,w(r))),e?(o=c,i=false):t.length>=200&&(o=Ln,i=false,t=new Mn(t));n:for(;++ur;)n=n[t[r++]];return r&&r==e?n:Z}function pt(n,t){return cu.call(n,t)||typeof n=="object"&&t in n&&null===xu(n)}function _t(n,t){return t in Object(n); -}function gt(n,t,r){for(var e=r?c:f,u=n.length,o=u,i=Array(u),l=[];o--;){var s=n[o];o&&t&&(s=a(s,w(t))),i[o]=r||!t&&120>s.length?Z:new Mn(o&&s)}var s=n[0],h=-1,p=s.length,_=i[0];n:for(;++h=f){e=c;break n}e=c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function Et(n,t){return n=Object(n),s(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function It(n,t){var r={};return ct(n,function(n,e){t(n,e)&&(r[e]=n)}),r}function St(n){return function(t){return null==t?Z:t[n]}}function Rt(n){return function(t){return ht(t,n)}}function Wt(n,t,r){ -var e=-1,u=t.length,o=n;for(r&&(o=a(n,function(n){return r(n)}));++et&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e=u){for(;u>e;){var o=e+u>>>1,i=n[o];(r?t>=i:t>i)&&null!==i?e=o+1:u=o; -}return u}return $t(n,t,Ve,r)}function $t(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,c=t===Z;o>u;){var a=Eu((u+o)/2),l=r(n[a]),s=l!==Z,h=l===l;(i?h||e:f?h&&s&&(e||null!=l):c?h&&(e||s):null==l?0:e?t>=l:t>l)?u=a+1:o=a}return Bu(o,4294967294)}function Ft(n,t){for(var r=0,e=n.length,u=n[0],o=t?t(u):u,i=o,f=0,c=[u];++re?t[e]:Z);return i}function Kt(n,t){if(t)return n.slice();var r=new n.constructor(n.length);return n.copy(r),r}function Gt(n){var t=new n.constructor(n.byteLength);return new du(t).set(new du(n)),t}function Vt(n,t,r){for(var e=r.length,u=-1,o=Wu(n.length-e,0),i=-1,f=t.length,c=Array(f+o);++i1?r[u-1]:Z,i=u>2?r[2]:Z,o=typeof o=="function"?(u--, -o):Z;for(i&&Br(r[0],r[1],i)&&(o=3>u?Z:o,u=1),t=Object(t);++ei&&c[0]!==l&&c[i-1]!==l?[]:L(c,l),i-=f.length,e>i?vr(n,t,lr,l,Z,c,f,Z,Z,e-i):r(a,this,c)}var o=fr(n);return u}function ar(n){return le(function(t){t=ft(t);var r=t.length,e=r,u=wn.prototype.thru; -for(n&&t.reverse();e--;){var o=t[e];if(typeof o!="function")throw new uu("Expected a function");if(u&&!i&&"wrapper"==mr(o))var i=new wn([],true)}for(e=i?e:r;++e=200)return i.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++uy)return vr(n,t,lr,b,r,x,j,f,c,a-y)}if(y=h?r:this,b=p?y[n]:n,f)for(var j=x.length,m=Bu(f.length,j),w=Yt(x);m--;){var A=f[m];x[m]=U(A,j)?w[A]:Z}else v&&x.length>1&&x.reverse();return s&&x.length>c&&(x.length=c),this&&this!==Vn&&this instanceof l&&(b=d||fr(b)),b.apply(y,x)}var s=128&t,h=1&t,p=2&t,_=8&t,g=16&t,v=512&t,d=p?Z:fr(n); -return l}function sr(n,t){return function(r,e){return vt(r,n,t(e),{})}}function hr(n){return le(function(t){return t=a(ft(t),wr()),le(function(e){var u=this;return n(t,function(n){return r(n,u,e)})})})}function pr(n,t,r){return t=We(t),n=F(n),t&&t>n?(t-=n,r=r===Z?" ":r+"",n=Te(r,ku(t/F(r))),En.test(r)?n.match(kn).slice(0,t).join(""):n.slice(0,t)):""}function _r(n,t,e,u){function o(){for(var t=-1,c=arguments.length,a=-1,l=u.length,s=Array(l+c),h=this&&this!==Vn&&this instanceof o?f:n;++at?1:-1:Ce(e)||0;var u=-1;r=Wu(ku((r-t)/(e||1)),0);for(var o=Array(r);r--;)o[n?r:++u]=t,t+=e;return o}}function vr(n,t,r,e,u,o,i,f,c,a){var l=8&t;f=f?Yt(f):Z;var s=l?i:Z;i=l?Z:i;var h=l?o:Z;return o=l?Z:o,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),t=[n,t,u,h,s,o,i,f,c,a],r=r.apply(Z,t), -zr(n)&&uo(r,t),r.placeholder=e,r}function dr(n){var t=ru[n];return function(n,r){if(n=Ce(n),r=We(r)){var e=(ze(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(ze(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function yr(n,t,r,e,u,o,i,f){var c=2&t;if(!c&&typeof n!="function")throw new uu("Expected a function");var a=e?e.length:0;if(a||(t&=-97,e=u=Z),i=i===Z?i:Wu(We(i),0),f=f===Z?f:We(f),a-=u?u.length:0,64&t){var l=e,s=u;e=u=Z}var h=c?Z:to(n);return o=[n,t,r,e,u,l,s,o,i,f],h&&(r=o[1],n=h[1], -t=r|n,e=128==n&&8==r||128==n&&256==r&&h[8]>=o[7].length||384==n&&h[8]>=h[7].length&&8==r,131>t||e)&&(1&n&&(o[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=o[3],o[3]=e?Vt(e,r,h[4]):Yt(r),o[4]=e?L(o[3],"__lodash_placeholder__"):Yt(h[4])),(r=h[5])&&(e=o[5],o[5]=e?Jt(e,r,h[6]):Yt(r),o[6]=e?L(o[5],"__lodash_placeholder__"):Yt(h[6])),(r=h[7])&&(o[7]=Yt(r)),128&n&&(o[8]=null==o[8]?h[8]:Bu(o[8],h[8])),null==o[9]&&(o[9]=h[9]),o[0]=h[0],o[1]=t),n=o[0],t=o[1],r=o[2],e=o[3],u=o[4],f=o[9]=null==o[9]?c?0:n.length:Wu(o[9]-a,0), -!f&&24&t&&(t&=-25),c=t&&1!=t?8==t||16==t?cr(n,t,f):32!=t&&33!=t||u.length?lr.apply(Z,o):_r(n,t,r,e):ur(n,t,r),(h?Xu:uo)(c,o)}function br(n,t,r,e,u,o){var i=-1,f=2&u,c=1&u,a=n.length,l=t.length;if(!(a==l||f&&l>a))return false;if(l=o.get(n))return l==t;for(l=true,o.set(n,t);++it?0:t,e)):[]}function Pr(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:We(t),t=e-t,zt(n,0,0>t?0:t)):[]}function Tr(n){return n?n[0]:Z}function Kr(n){var t=n?n.length:0;return t?n[t-1]:Z}function Gr(n,t){return n&&n.length&&t&&t.length?Wt(n,t):n; -}function Vr(n){return n?zu.call(n):n}function Jr(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){return ge(n)?(t=Wu(n.length,t),true):void 0}),j(t,function(t){return a(n,St(t))})}function Yr(n,t){if(!n||!n.length)return[];var e=Jr(n);return null==t?e:a(e,function(n){return r(t,Z,n)})}function Hr(n){return n=yn(n),n.__chain__=true,n}function Qr(n,t){return t(n)}function Xr(){return this}function ne(n,t){return typeof t=="function"&&No(n)?u(n,t):Ju(n,Dr(t))}function te(n,t){var r;if(typeof t=="function"&&No(n)){ -for(r=n.length;r--&&false!==t(n[r],r,n););r=n}else r=Yu(n,Dr(t));return r}function re(n,t){return(No(n)?a:mt)(n,wr(t,3))}function ee(n,t){var r=-1,e=Re(n),u=e.length,o=u-1;for(t=nt(We(t),0,u);++r=n&&(t=Z),r}}function ie(n,t,r){ -return t=r?Z:t,n=yr(n,8,Z,Z,Z,Z,Z,t),n.placeholder=yn.placeholder||ie.placeholder,n}function fe(n,t,r){return t=r?Z:t,n=yr(n,16,Z,Z,Z,Z,Z,t),n.placeholder=yn.placeholder||fe.placeholder,n}function ce(n,t,r){function e(){p&&yu(p),a&&yu(a),g=0,c=a=h=p=_=Z}function u(t,r){r&&yu(r),a=p=_=Z,t&&(g=Wo(),l=n.apply(h,c),p||a||(c=h=Z))}function o(){var n=t-(Wo()-s);0>=n||n>t?u(_,a):p=Au(o,n)}function i(){u(y,p)}function f(){if(c=arguments,s=Wo(),h=this,_=y&&(p||!v),false===d)var r=v&&!p;else{g||a||v||(g=s);var e=d-(s-g),u=0>=e||e>d; -u?(a&&(a=yu(a)),g=s,l=n.apply(h,c)):a||(a=Au(i,e))}return u&&p?p=yu(p):p||t===d||(p=Au(o,t)),r&&(u=true,l=n.apply(h,c)),!u||p||a||(c=h=Z),l}var c,a,l,s,h,p,_,g=0,v=false,d=false,y=true;if(typeof n!="function")throw new uu("Expected a function");return t=Ce(t)||0,xe(r)&&(v=!!r.leading,d="maxWait"in r&&Wu(Ce(r.maxWait)||0,t),y="trailing"in r?!!r.trailing:y),f.cancel=e,f.flush=function(){return(p&&_||a&&y)&&(l=n.apply(h,c)),e(),l},f}function ae(n,t){if(typeof n!="function"||t&&typeof t!="function")throw new uu("Expected a function"); -var r=function(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)};return r.cache=new ae.Cache,r}function le(n,t){if(typeof n!="function")throw new uu("Expected a function");return t=Wu(t===Z?n.length-1:We(t),0),function(){for(var e=arguments,u=-1,o=Wu(e.length-t,0),i=Array(o);++ut}function pe(n){return ge(n)&&cu.call(n,"callee")&&(!wu.call(n,"callee")||"[object Arguments]"==su.call(n))}function _e(n){return null!=n&&!(typeof n=="function"&&de(n))&&be(ro(n))}function ge(n){return je(n)&&_e(n)}function ve(n){return je(n)&&typeof n.message=="string"&&"[object Error]"==su.call(n)}function de(n){return n=xe(n)?su.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function ye(n){ -return typeof n=="number"&&n==We(n)}function be(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function xe(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function je(n){return!!n&&typeof n=="object"}function me(n){return null==n?false:de(n)?pu.test(fu.call(n)):je(n)&&(C(n)?pu:vn).test(n)}function we(n){return typeof n=="number"||je(n)&&"[object Number]"==su.call(n)}function Ae(n){if(!je(n)||"[object Object]"!=su.call(n)||C(n))return false;var t=iu;return typeof n.constructor=="function"&&(t=xu(n)), -null===t?true:(n=t.constructor,typeof n=="function"&&n instanceof n&&fu.call(n)==lu)}function Oe(n){return xe(n)&&"[object RegExp]"==su.call(n)}function ke(n){return typeof n=="string"||!No(n)&&je(n)&&"[object String]"==su.call(n)}function Ee(n){return typeof n=="symbol"||je(n)&&"[object Symbol]"==su.call(n)}function Ie(n){return je(n)&&be(n.length)&&!!Bn[su.call(n)]}function Se(n,t){return t>n}function Re(n){if(!n)return[];if(_e(n))return ke(n)?n.match(kn):Yt(n);if(mu&&n[mu])return z(n[mu]());var t=kr(n); -return("[object Map]"==t?M:"[object Set]"==t?$:Ze)(n)}function We(n){if(!n)return 0===n?n:0;if(n=Ce(n),n===q||n===-q)return 1.7976931348623157e308*(0>n?-1:1);var t=n%1;return n===n?t?n-t:n:0}function Be(n){return n?nt(We(n),0,4294967295):0}function Ce(n){if(xe(n)&&(n=de(n.valueOf)?n.valueOf():n,n=xe(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(fn,"");var t=gn.test(n);return t||dn.test(n)?Nn(n.slice(2),t?2:8):_n.test(n)?P:+n}function Ue(n){return Ht(n,Ne(n))}function ze(n){if(typeof n=="string")return n; -if(null==n)return"";if(Ee(n))return vu?Ku.call(n):"";var t=n+"";return"0"==t&&1/n==-q?"-0":t}function Me(n,t,r){return n=null==n?Z:ht(n,t),n===Z?r:n}function Le(n,t){return Er(n,t,pt)}function $e(n,t){return Er(n,t,_t)}function Fe(n){var t=Mr(n);if(!t&&!_e(n))return Ru(Object(n));var r,e=Wr(n),u=!!e,e=e||[],o=e.length;for(r in n)!pt(n,r)||u&&("length"==r||U(r,o))||t&&"constructor"==r||e.push(r);return e}function Ne(n){for(var t=-1,r=Mr(n),e=jt(n),u=e.length,o=Wr(n),i=!!o,o=o||[],f=o.length;++tt||t>9007199254740991)return r;do t%2&&(r+=n),t=Eu(t/2),n+=n;while(t);return r}function Ke(n,t,r){return n=ze(n),t=r?Z:t,t===Z&&(t=Rn.test(n)?Sn:In),n.match(t)||[]}function Ge(n){ -return function(){return n}}function Ve(n){return n}function Je(n){return xt(typeof n=="function"?n:tt(n,true))}function Ye(n,t,r){var e=Fe(t),o=st(t,e);null!=r||xe(t)&&(o.length||!e.length)||(r=t,t=n,n=this,o=st(t,Fe(t)));var i=xe(r)&&"chain"in r?r.chain:true,f=de(n);return u(o,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(i||t){var r=n(this.__wrapped__);return(r.__actions__=Yt(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,l([this.value()],arguments)); -})}),n}function He(){}function Qe(n){return Cr(n)?St(n):Rt(n)}function Xe(n){return n&&n.length?x(n,Ve):0}E=E?Jn.defaults({},E,Jn.pick(Vn,Wn)):Vn;var nu=E.Date,tu=E.Error,ru=E.Math,eu=E.RegExp,uu=E.TypeError,ou=E.Array.prototype,iu=E.Object.prototype,fu=E.Function.prototype.toString,cu=iu.hasOwnProperty,au=0,lu=fu.call(Object),su=iu.toString,hu=Vn._,pu=eu("^"+fu.call(cu).replace(un,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),_u=Kn?E.Buffer:Z,gu=E.Reflect,vu=E.Symbol,du=E.Uint8Array,yu=E.clearTimeout,bu=gu?gu.enumerate:Z,xu=Object.getPrototypeOf,ju=Object.getOwnPropertySymbols,mu=typeof(mu=vu&&vu.iterator)=="symbol"?mu:Z,wu=iu.propertyIsEnumerable,Au=E.setTimeout,Ou=ou.splice,ku=ru.ceil,Eu=ru.floor,Iu=E.isFinite,Su=ou.join,Ru=Object.keys,Wu=ru.max,Bu=ru.min,Cu=E.parseInt,Uu=ru.random,zu=ou.reverse,Mu=Or(E,"Map"),Lu=Or(E,"Set"),$u=Or(E,"WeakMap"),Fu=Or(Object,"create"),Nu=$u&&new $u,Du=Mu?fu.call(Mu):"",Zu=Lu?fu.call(Lu):"",qu=$u?fu.call($u):"",Pu=vu?vu.prototype:Z,Tu=vu?Pu.valueOf:Z,Ku=vu?Pu.toString:Z,Gu={}; -yn.templateSettings={escape:Q,evaluate:X,interpolate:nn,variable:"",imports:{_:yn}};var Vu=function(){function n(){}return function(t){if(xe(t)){n.prototype=t;var r=new n;n.prototype=Z}return r||{}}}(),Ju=rr(at),Yu=rr(lt,true),Hu=er(),Qu=er(true);bu&&!wu.call({valueOf:1},"valueOf")&&(jt=function(n){return z(bu(n))});var Xu=Nu?function(n,t){return Nu.set(n,t),n}:Ve,no=Lu&&2===new Lu([1,2]).size?function(n){return new Lu(n)}:He,to=Nu?function(n){return Nu.get(n)}:He,ro=St("length"),eo=ju||function(){return[]; -};(Mu&&"[object Map]"!=kr(new Mu)||Lu&&"[object Set]"!=kr(new Lu)||$u&&"[object WeakMap]"!=kr(new $u))&&(kr=function(n){var t=su.call(n);if(n="[object Object]"==t?n.constructor:null,n=typeof n=="function"?fu.call(n):"")switch(n){case Du:return"[object Map]";case Zu:return"[object Set]";case qu:return"[object WeakMap]"}return t});var uo=function(){var n=0,t=0;return function(r,e){var u=Wo(),o=16-(u-t);if(t=u,o>0){if(150<=++n)return r}else n=0;return Xu(r,e)}}(),oo=le(function(n,t){No(n)||(n=null==n?[]:[Object(n)]), -t=ft(t);for(var r=n,e=t,u=-1,o=r.length,i=-1,f=e.length,c=Array(o+f);++u1?n[t-1]:Z,t=typeof t=="function"?(n.pop(),t):Z;return Yr(n,t)}),Ao=le(function(n){n=ft(n);var t=n.length,r=t?n[0]:0,e=this.__wrapped__,u=function(t){return Xn(t,n)};return 1>=t&&!this.__actions__.length&&e instanceof An&&U(r)?(e=e.slice(r,+r+(t?1:0)),e.__actions__.push({func:Qr,args:[u],thisArg:Z}),new wn(e,this.__chain__).thru(function(n){return t&&!n.length&&n.push(Z), -n})):this.thru(u)}),Oo=nr(function(n,t,r){cu.call(n,r)?++n[r]:n[r]=1}),ko=nr(function(n,t,r){cu.call(n,r)?n[r].push(t):n[r]=[t]}),Eo=le(function(n,t,e){var u=-1,o=typeof t=="function",i=Cr(t),f=_e(n)?Array(n.length):[];return Ju(n,function(n){var c=o?t:i&&null!=n?n[t]:Z;f[++u]=c?r(c,n,e):dt(n,t,e)}),f}),Io=nr(function(n,t,r){n[r]=t}),So=nr(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Ro=le(function(n,t){if(null==n)return[];var r=t.length;return r>1&&Br(n,t[0],t[1])?t=[]:r>2&&Br(t[0],t[1],t[2])&&(t.length=1), -kt(n,ft(t),[])}),Wo=nu.now,Bo=le(function(n,t,r){var e=1;if(r.length)var u=L(r,yn.placeholder||Bo.placeholder),e=32|e;return yr(n,e,t,r,u)}),Co=le(function(n,t,r){var e=3;if(r.length)var u=L(r,yn.placeholder||Co.placeholder),e=32|e;return yr(t,e,n,r,u)}),Uo=le(function(n,t){return et(n,1,t)}),zo=le(function(n,t,r){return et(n,Ce(t)||0,r)}),Mo=le(function(n,t){t=a(ft(t),wr());var e=t.length;return le(function(u){for(var o=-1,i=Bu(u.length,e);++oe.length?Pn(e,n,t):(r.array=null,r.map=new zn(e))),(r=r.map)&&r.set(n,t),this},ae.Cache=zn,yn.after=function(n,t){if(typeof t!="function")throw new uu("Expected a function");return n=We(n),function(){return 1>--n?t.apply(this,arguments):void 0}},yn.ary=ue,yn.assign=Zo,yn.assignIn=qo,yn.assignInWith=Po,yn.assignWith=To,yn.at=Ko,yn.before=oe,yn.bind=Bo,yn.bindAll=si,yn.bindKey=Co,yn.chain=Hr,yn.chunk=function(n,t){t=Wu(We(t),0); -var r=n?n.length:0;if(!r||1>t)return[];for(var e=0,u=-1,o=Array(ku(r/t));r>e;)o[++u]=zt(n,e,e+=t);return o},yn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++tr&&(r=-r>u?0:u+r),e=e===Z||e>u?u:We(e),0>e&&(e+=u),e=r>e?0:Be(e);e>r;)n[r++]=t;return n},yn.filter=function(n,t){return(No(n)?i:it)(n,wr(t,3))},yn.flatMap=function(n,t){return ft(re(n,t))},yn.flatten=function(n){return n&&n.length?ft(n):[]},yn.flattenDeep=function(n){return n&&n.length?ft(n,true):[]},yn.flip=function(n){return yr(n,512)},yn.flow=hi,yn.flowRight=pi,yn.fromPairs=function(n){for(var t=-1,r=n?n.length:0,e={};++tt?0:t)):[]},yn.takeRight=function(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:We(t),t=e-t,zt(n,0>t?0:t,e)):[]},yn.takeRightWhile=function(n,t){return n&&n.length?Zt(n,wr(t,3),false,true):[]},yn.takeWhile=function(n,t){return n&&n.length?Zt(n,wr(t,3)):[]},yn.tap=function(n,t){return t(n),n},yn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new uu("Expected a function");return xe(r)&&(e="leading"in r?!!r.leading:e, -u="trailing"in r?!!r.trailing:u),ce(n,t,{leading:e,maxWait:t,trailing:u})},yn.thru=Qr,yn.toArray=Re,yn.toPairs=De,yn.toPairsIn=function(n){return m(n,Ne(n))},yn.toPath=function(n){return No(n)?a(n,String):Fr(n)},yn.toPlainObject=Ue,yn.transform=function(n,t,r){var e=No(n)||Ie(n);if(t=wr(t,4),null==r)if(e||xe(n)){var o=n.constructor;r=e?No(n)?new o:[]:Vu(de(o)?o.prototype:Z)}else r={};return(e?u:at)(n,function(n,e,u){return t(r,n,e,u)}),r},yn.unary=function(n){return ue(n,1)},yn.union=_o,yn.unionBy=go, -yn.unionWith=vo,yn.uniq=function(n){return n&&n.length?Dt(n):[]},yn.uniqBy=function(n,t){return n&&n.length?Dt(n,wr(t)):[]},yn.uniqWith=function(n,t){return n&&n.length?Dt(n,Z,t):[]},yn.unset=function(n,t){var r;if(null==n)r=true;else{r=n;var e=t,e=Cr(e,r)?[e+""]:Nt(e);r=$r(r,e),e=Kr(e),r=null!=r&&Le(r,e)?delete r[e]:true}return r},yn.unzip=Jr,yn.unzipWith=Yr,yn.values=Ze,yn.valuesIn=function(n){return null==n?A(n,Ne(n)):[]},yn.without=yo,yn.words=Ke,yn.wrap=function(n,t){return t=null==t?Ve:t,Lo(t,n); -},yn.xor=bo,yn.xorBy=xo,yn.xorWith=jo,yn.zip=mo,yn.zipObject=function(n,t){return Tt(n||[],t||[],Yn)},yn.zipObjectDeep=function(n,t){return Tt(n||[],t||[],Ut)},yn.zipWith=wo,yn.extend=qo,yn.extendWith=Po,Ye(yn,yn),yn.add=function(n,t){var r;return n===Z&&t===Z?0:(n!==Z&&(r=n),t!==Z&&(r=r===Z?t:r+t),r)},yn.attempt=li,yn.camelCase=ri,yn.capitalize=qe,yn.ceil=ji,yn.clamp=function(n,t,r){return r===Z&&(r=t,t=Z),r!==Z&&(r=Ce(r),r=r===r?r:0),t!==Z&&(t=Ce(t),t=t===t?t:0),nt(Ce(n),t,r)},yn.clone=function(n){ -return tt(n)},yn.cloneDeep=function(n){return tt(n,true)},yn.cloneDeepWith=function(n,t){return tt(n,true,t)},yn.cloneWith=function(n,t){return tt(n,false,t)},yn.deburr=Pe,yn.endsWith=function(n,t,r){n=ze(n),t=typeof t=="string"?t:t+"";var e=n.length;return r=r===Z?e:nt(We(r),0,e),r-=t.length,r>=0&&n.indexOf(t,r)==r},yn.eq=se,yn.escape=function(n){return(n=ze(n))&&H.test(n)?n.replace(J,R):n},yn.escapeRegExp=function(n){return(n=ze(n))&&on.test(n)?n.replace(un,"\\$&"):n},yn.every=function(n,t,r){var e=No(n)?o:ot; -return r&&Br(n,t,r)&&(t=Z),e(n,wr(t,3))},yn.find=function(n,t){if(t=wr(t,3),No(n)){var r=v(n,t);return r>-1?n[r]:Z}return g(n,t,Ju)},yn.findIndex=function(n,t){return n&&n.length?v(n,wr(t,3)):-1},yn.findKey=function(n,t){return g(n,wr(t,3),at,true)},yn.findLast=function(n,t){if(t=wr(t,3),No(n)){var r=v(n,t,true);return r>-1?n[r]:Z}return g(n,t,Yu)},yn.findLastIndex=function(n,t){return n&&n.length?v(n,wr(t,3),true):-1},yn.findLastKey=function(n,t){return g(n,wr(t,3),lt,true)},yn.floor=mi,yn.forEach=ne,yn.forEachRight=te, -yn.forIn=function(n,t){return null==n?n:Hu(n,Dr(t),Ne)},yn.forInRight=function(n,t){return null==n?n:Qu(n,Dr(t),Ne)},yn.forOwn=function(n,t){return n&&at(n,Dr(t))},yn.forOwnRight=function(n,t){return n&<(n,Dr(t))},yn.get=Me,yn.gt=he,yn.gte=function(n,t){return n>=t},yn.has=Le,yn.hasIn=$e,yn.head=Tr,yn.identity=Ve,yn.includes=function(n,t,r,e){return n=_e(n)?n:Ze(n),r=r&&!e?We(r):0,e=n.length,0>r&&(r=Wu(e+r,0)),ke(n)?e>=r&&-1r&&(r=Wu(e+r,0)),d(n,t,r)):-1},yn.inRange=function(n,t,r){return t=Ce(t)||0,r===Z?(r=t,t=0):r=Ce(r)||0,n=Ce(n),n>=Bu(t,r)&&n=-9007199254740991&&9007199254740991>=n},yn.isSet=function(n){return je(n)&&"[object Set]"==kr(n)},yn.isString=ke,yn.isSymbol=Ee, -yn.isTypedArray=Ie,yn.isUndefined=function(n){return n===Z},yn.isWeakMap=function(n){return je(n)&&"[object WeakMap]"==kr(n)},yn.isWeakSet=function(n){return je(n)&&"[object WeakSet]"==su.call(n)},yn.join=function(n,t){return n?Su.call(n,t):""},yn.kebabCase=ei,yn.last=Kr,yn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(r!==Z&&(u=We(r),u=(0>u?Wu(e+u,0):Bu(u,e-1))+1),t!==t)return B(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},yn.lowerCase=ui,yn.lowerFirst=oi,yn.lt=Se, -yn.lte=function(n,t){return t>=n},yn.max=function(n){return n&&n.length?_(n,Ve,he):Z},yn.maxBy=function(n,t){return n&&n.length?_(n,wr(t),he):Z},yn.mean=function(n){return Xe(n)/(n?n.length:0)},yn.min=function(n){return n&&n.length?_(n,Ve,Se):Z},yn.minBy=function(n,t){return n&&n.length?_(n,wr(t),Se):Z},yn.noConflict=function(){return Vn._===this&&(Vn._=hu),this},yn.noop=He,yn.now=Wo,yn.pad=function(n,t,r){n=ze(n),t=We(t);var e=F(n);return t&&t>e?(e=(t-e)/2,t=Eu(e),e=ku(e),pr("",t,r)+n+pr("",e,r)):n; -},yn.padEnd=function(n,t,r){return n=ze(n),n+pr(n,t,r)},yn.padStart=function(n,t,r){return n=ze(n),pr(n,t,r)+n},yn.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),n=ze(n).replace(fn,""),Cu(n,t||(pn.test(n)?16:10))},yn.random=function(n,t,r){if(r&&typeof r!="boolean"&&Br(n,t,r)&&(t=r=Z),r===Z&&(typeof t=="boolean"?(r=t,t=Z):typeof n=="boolean"&&(r=n,n=Z)),n===Z&&t===Z?(n=0,t=1):(n=Ce(n)||0,t===Z?(t=n,n=0):t=Ce(t)||0),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Uu(),Bu(n+r*(t-n+Fn("1e-"+((r+"").length-1))),t)):Ct(n,t); -},yn.reduce=function(n,t,r){var e=No(n)?s:y,u=3>arguments.length;return e(n,wr(t,4),r,u,Ju)},yn.reduceRight=function(n,t,r){var e=No(n)?h:y,u=3>arguments.length;return e(n,wr(t,4),r,u,Yu)},yn.repeat=Te,yn.replace=function(){var n=arguments,t=ze(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},yn.result=function(n,t,r){if(Cr(t,n))e=null==n?Z:n[t];else{t=Nt(t);var e=Me(n,t);n=$r(n,t)}return e===Z&&(e=r),de(e)?e.call(n):e},yn.round=wi,yn.runInContext=D,yn.sample=function(n){n=_e(n)?n:Ze(n);var t=n.length; -return t>0?n[Ct(0,t-1)]:Z},yn.size=function(n){if(null==n)return 0;if(_e(n)){var t=n.length;return t&&ke(n)?F(n):t}return Fe(n).length},yn.snakeCase=fi,yn.some=function(n,t,r){var e=No(n)?p:Mt;return r&&Br(n,t,r)&&(t=Z),e(n,wr(t,3))},yn.sortedIndex=function(n,t){return Lt(n,t)},yn.sortedIndexBy=function(n,t,r){return $t(n,t,wr(r))},yn.sortedIndexOf=function(n,t){var r=n?n.length:0;if(r){var e=Lt(n,t);if(r>e&&se(n[e],t))return e}return-1},yn.sortedLastIndex=function(n,t){return Lt(n,t,true)},yn.sortedLastIndexBy=function(n,t,r){ -return $t(n,t,wr(r),true)},yn.sortedLastIndexOf=function(n,t){if(n&&n.length){var r=Lt(n,t,true)-1;if(se(n[r],t))return r}return-1},yn.startCase=ci,yn.startsWith=function(n,t,r){return n=ze(n),r=nt(We(r),0,n.length),n.lastIndexOf(t,r)==r},yn.subtract=function(n,t){var r;return n===Z&&t===Z?0:(n!==Z&&(r=n),t!==Z&&(r=r===Z?t:r-t),r)},yn.sum=Xe,yn.sumBy=function(n,t){return n&&n.length?x(n,wr(t)):0},yn.template=function(n,t,r){var e=yn.templateSettings;r&&Br(n,t,r)&&(t=Z),n=ze(n),t=Po({},t,e,Tn),r=Po({},t.imports,e.imports,Tn); -var u,o,i=Fe(r),f=A(r,i),c=0;r=t.interpolate||xn;var a="__p+='";r=eu((t.escape||xn).source+"|"+r.source+"|"+(r===nn?sn:xn).source+"|"+(t.evaluate||xn).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,i,f,l){return e||(e=i),a+=n.slice(c,l).replace(jn,W),r&&(u=true,a+="'+__e("+r+")+'"),f&&(o=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(o?a.replace(T,""):a).replace(K,"$1").replace(G,"$1;"), -a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=li(function(){return Function(i,l+"return "+a).apply(Z,f)}),t.source=a,ve(t))throw t;return t},yn.times=function(n,t){if(n=We(n),1>n||n>9007199254740991)return[];var r=4294967295,e=Bu(n,4294967295);for(t=Dr(t),n-=4294967295,e=j(e,t);++r=o)return n;if(o=r-F(e),1>o)return e;if(r=i?i.slice(0,o).join(""):n.slice(0,o),u===Z)return r+e;if(i&&(o+=r.length-o),Oe(u)){if(n.slice(o).search(u)){var f=r;for(u.global||(u=eu(u.source,ze(hn.exec(u))+"g")),u.lastIndex=0;i=u.exec(f);)var c=i.index; -r=r.slice(0,c===Z?o:c)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),u>-1&&(r=r.slice(0,u)));return r+e},yn.unescape=function(n){return(n=ze(n))&&Y.test(n)?n.replace(V,N):n},yn.uniqueId=function(n){var t=++au;return ze(n)+t},yn.upperCase=ai,yn.upperFirst=ii,yn.each=ne,yn.eachRight=te,yn.first=Tr,Ye(yn,function(){var n={};return at(yn,function(t,r){cu.call(yn.prototype,r)||(n[r]=t)}),n}(),{chain:false}),yn.VERSION="4.3.0",u("bind bindKey curry curryRight partial partialRight".split(" "),function(n){yn[n].placeholder=yn; -}),u(["drop","take"],function(n,t){An.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new An(this);r=r===Z?1:Wu(We(r),0);var u=this.clone();return e?u.__takeCount__=Bu(r,u.__takeCount__):u.__views__.push({size:Bu(r,4294967295),type:n+(0>u.__dir__?"Right":"")}),u},An.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),u(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;An.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({ -iteratee:wr(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),u(["head","last"],function(n,t){var r="take"+(t?"Right":"");An.prototype[n]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");An.prototype[n]=function(){return this.__filtered__?new An(this):this[r](1)}}),An.prototype.compact=function(){return this.filter(Ve)},An.prototype.find=function(n){return this.filter(n).head()},An.prototype.findLast=function(n){return this.reverse().find(n); -},An.prototype.invokeMap=le(function(n,t){return typeof n=="function"?new An(this):this.map(function(r){return dt(r,n,t)})}),An.prototype.reject=function(n){return n=wr(n,3),this.filter(function(t){return!n(t)})},An.prototype.slice=function(n,t){n=We(n);var r=this;return r.__filtered__&&(n>0||0>t)?new An(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==Z&&(t=We(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},An.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},An.prototype.toArray=function(){ -return this.take(4294967295)},at(An.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=yn[e?"take"+("last"==t?"Right":""):t],o=e||/^find/.test(t);u&&(yn.prototype[t]=function(){var t=this.__wrapped__,i=e?[1]:arguments,f=t instanceof An,c=i[0],a=f||No(t),s=function(n){return n=u.apply(yn,l([n],i)),e&&h?n[0]:n};a&&r&&typeof c=="function"&&1!=c.length&&(f=a=false);var h=this.__chain__,p=!!this.__actions__.length,c=o&&!h,f=f&&!p;return!o&&a?(t=f?t:new An(this), -t=n.apply(t,i),t.__actions__.push({func:Qr,args:[s],thisArg:Z}),new wn(t,h)):c&&f?n.apply(this,i):(t=this.thru(s),c?e?t.value()[0]:t.value():t)})}),u("pop push shift sort splice unshift".split(" "),function(n){var t=ou[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);yn.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),at(An.prototype,function(n,t){var r=yn[t];if(r){var e=r.name+"";(Gu[e]||(Gu[e]=[])).push({ -name:t,func:r})}}),Gu[lr(Z,2).name]=[{name:"wrapper",func:Z}],An.prototype.clone=function(){var n=new An(this.__wrapped__);return n.__actions__=Yt(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Yt(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Yt(this.__views__),n},An.prototype.reverse=function(){if(this.__filtered__){var n=new An(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},An.prototype.value=function(){ -var n,t=this.__wrapped__.value(),r=this.__dir__,e=No(t),u=0>r,o=e?t.length:0;n=0;for(var i=o,f=this.__views__,c=-1,a=f.length;++co||o==n&&a==n)return qt(t,this.__actions__);e=[];n:for(;n--&&a>c;){for(u+=r,o=-1,l=t[u];++o=this.__values__.length,t=n?Z:this.__values__[this.__index__++];return{done:n,value:t}},yn.prototype.plant=function(n){ -for(var t,r=this;r instanceof mn;){var e=Zr(r);e.__index__=0,e.__values__=Z,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},yn.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof An?(this.__actions__.length&&(n=new An(this)),n=n.reverse(),n.__actions__.push({func:Qr,args:[Vr],thisArg:Z}),new wn(n,this.__chain__)):this.thru(Vr)},yn.prototype.toJSON=yn.prototype.valueOf=yn.prototype.value=function(){return qt(this.__wrapped__,this.__actions__)},mu&&(yn.prototype[mu]=Xr), -yn}var Z,q=1/0,P=NaN,T=/\b__p\+='';/g,K=/\b(__p\+=)''\+/g,G=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39|#96);/g,J=/[&<>"'`]/g,Y=RegExp(V.source),H=RegExp(J.source),Q=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,nn=/<%=([\s\S]+?)%>/g,tn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,rn=/^\w*$/,en=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,un=/[\\^$.*+?()[\]{}|]/g,on=RegExp(un.source),fn=/^\s+|\s+$/g,cn=/^\s+/,an=/\s+$/,ln=/\\(\\)?/g,sn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,hn=/\w*$/,pn=/^0x/i,_n=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,vn=/^\[object .+?Constructor\]$/,dn=/^0o[0-7]+$/i,yn=/^(?:0|[1-9]\d*)$/,bn=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,xn=/($^)/,jn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",wn="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,An="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",On=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]","g"),kn=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+An+mn,"g"),En=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),In=/[a-zA-Z0-9]+/g,Sn=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|\\d+",wn].join("|"),"g"),Rn=/[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={}; +r[++t]=n}),r}function F(n){if(!n||!En.test(n))return n.length;for(var t=kn.lastIndex=0;kn.test(n);)t++;return t}function N(n){return Mn[n]}function D(E){function yn(n){if(me(n)&&!Do(n)&&!(n instanceof An)){if(n instanceof wn)return n;if(au.call(n,"__wrapped__"))return qr(n)}return new wn(n)}function mn(){}function wn(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=Z}function An(n){this.__wrapped__=n,this.__actions__=[],this.__dir__=1,this.__filtered__=false, +this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Un(){}function zn(n){var t=-1,r=n?n.length:0;for(this.clear();++tr?false:(r==n.length-1?n.pop():Eu.call(n,r,1),true)}function Zn(n,t){var r=Pn(n,t);return 0>r?Z:n[r][1]}function Pn(n,t){for(var r=n.length;r--;)if(he(n[r][0],t))return r;return-1}function Tn(n,t,r){var e=Pn(n,t);0>e?n.push([t,r]):n[e][1]=r}function Kn(n,t,r,e){return n===Z||he(n,fu[r])&&!au.call(e,r)?t:n}function Jn(n,t,r){(r!==Z&&!he(n[t],r)||typeof t=="number"&&r===Z&&!(t in n))&&(n[t]=r)}function Yn(n,t,r){var e=n[t];(!he(e,r)||he(e,fu[t])&&!au.call(n,t)||r===Z&&!(t in n))&&(n[t]=r); +}function Hn(n,t,r,e){return Yu(n,function(n,u,o){t(e,n,r(n),o)}),e}function Qn(n,t){return n&&nr(t,Ne(t),n)}function Xn(n,t){for(var r=-1,e=null==n,u=t.length,o=Array(u);++rr?r:n),t!==Z&&(n=t>n?t:n)),n}function ut(n,t,r,e,o,i){var f;if(r&&(f=o?r(n,e,o,i):r(n)),f!==Z)return f;if(!je(n))return n;if(e=Do(n)){ +if(f=Wr(n),!t)return Xt(n,f)}else{var c=Sr(n),a="[object Function]"==c||"[object GeneratorFunction]"==c;if(Zo(n))return Jt(n,t);if("[object Object]"!=c&&"[object Arguments]"!=c&&(!a||o))return Cn[c]?Cr(n,c,t):o?n:{};if(C(n))return o?n:{};if(f=Br(a?{}:n),!t)return rr(n,Qn(f,n))}return i||(i=new $n),(o=i.get(n))?o:(i.set(n,f),(e?u:pt)(n,function(e,u){Yn(f,u,ut(e,t,r,u,n,i))}),e?f:rr(n,f))}function ot(n){var t=Ne(n),r=t.length;return function(e){if(null==e)return!r;for(var u=r;u--;){var o=t[u],i=n[o],f=e[o]; +if(f===Z&&!(o in Object(e))||!i(f))return false}return true}}function it(n){return je(n)?Au(n):{}}function ft(n,t,r){if(typeof n!="function")throw new ou("Expected a function");return ku(function(){n.apply(Z,r)},t)}function ct(n,t,r,e){var u=-1,o=f,i=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=a(t,w(r))),e?(o=c,i=false):t.length>=200&&(o=Ln,i=false,t=new Mn(t));n:for(;++u0&&ve(i)&&(r||Do(i)||_e(i))?t>1?st(i,t-1,r,e):l(e,i):r||(e[e.length]=i)}return e}function ht(n,t){null==n||Qu(n,t,De)}function pt(n,t){return n&&Qu(n,t,Ne)}function _t(n,t){return n&&Xu(n,t,Ne)}function gt(n,t){return i(t,function(t){return ye(n[t])})}function vt(n,t){t=Mr(t,n)?[t+""]:rt(t); +for(var r=0,e=t.length;null!=n&&e>r;)n=n[t[r++]];return r&&r==e?n:Z}function dt(n,t){return au.call(n,t)||typeof n=="object"&&t in n&&null===ju(n)}function yt(n,t){return t in Object(n)}function bt(n,t,r){for(var e=r?c:f,u=n.length,o=u,i=Array(u),l=[];o--;){var s=n[o];o&&t&&(s=a(s,w(t))),i[o]=r||!t&&120>s.length?Z:new Mn(o&&s)}var s=n[0],h=-1,p=s.length,_=i[0];n:for(;++he?c*("desc"==r[e]?-1:1):c;break n}}e=n.b-t.b}return e})}function Wt(n,t){return n=Object(n),s(t,function(t,r){return r in n&&(t[r]=n[r]),t},{})}function Bt(n,t){ +var r={};return ht(n,function(n,e){t(n,e)&&(r[e]=n)}),r}function Ct(n){return function(t){return null==t?Z:t[n]}}function Ut(n){return function(t){return vt(t,n)}}function zt(n,t,r){var e=-1,u=t.length,o=n;for(r&&(o=a(n,function(n){return r(n)}));++et&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Array(u);++e=u){for(;u>e;){var o=e+u>>>1,i=n[o];(r?t>=i:t>i)&&null!==i?e=o+1:u=o}return u}return Zt(n,t,Je,r)}function Zt(n,t,r,e){t=r(t);for(var u=0,o=n?n.length:0,i=t!==t,f=null===t,c=t===Z;o>u;){var a=Su((u+o)/2),l=r(n[a]),s=l!==Z,h=l===l;(i?h||e:f?h&&s&&(e||null!=l):c?h&&(e||s):null==l?0:e?t>=l:t>l)?u=a+1:o=a}return Uu(o,4294967294)}function qt(n,t){for(var r=0,e=n.length,u=n[0],o=t?t(u):u,i=o,f=0,c=[u];++re?t[e]:Z);return i}function Jt(n,t){if(t)return n.slice();var r=new n.constructor(n.length);return n.copy(r),r}function Yt(n){var t=new n.constructor(n.byteLength);return new yu(t).set(new yu(n)), +t}function Ht(n,t,r){for(var e=r.length,u=-1,o=Cu(n.length-e,0),i=-1,f=t.length,c=Array(f+o);++i1?r[u-1]:Z,i=u>2?r[2]:Z,o=typeof o=="function"?(u--,o):Z;for(i&&zr(r[0],r[1],i)&&(o=3>u?Z:o,u=1),t=Object(t);++ei&&c[0]!==l&&c[i-1]!==l?[]:L(c,l),i-=f.length,e>i?br(n,t,pr,l,Z,c,f,Z,Z,e-i):r(a,this,c)}var o=lr(n);return u}function hr(n){return se(function(t){t=st(t,1);var r=t.length,e=r,u=wn.prototype.thru;for(n&&t.reverse();e--;){var o=t[e];if(typeof o!="function")throw new ou("Expected a function");if(u&&!i&&"wrapper"==Or(o))var i=new wn([],true)}for(e=i?e:r;++e=200)return i.plant(e).value();for(var u=0,n=r?t[u].apply(this,n):e;++uy)return br(n,t,pr,b,r,x,j,f,c,a-y)}if(y=h?r:this,b=p?y[n]:n,f)for(var j=x.length,m=Uu(f.length,j),w=Xt(x);m--;){ +var A=f[m];x[m]=U(A,j)?w[A]:Z}else v&&x.length>1&&x.reverse();return s&&x.length>c&&(x.length=c),this&&this!==Gn&&this instanceof l&&(b=d||lr(b)),b.apply(y,x)}var s=128&t,h=1&t,p=2&t,_=8&t,g=16&t,v=512&t,d=p?Z:lr(n);return l}function _r(n,t){return function(r,e){return xt(r,n,t(e))}}function gr(n){return se(function(t){return t=a(st(t,1),kr()),se(function(e){var u=this;return n(t,function(n){return r(n,u,e)})})})}function vr(n,t,r){return t=Be(t),n=F(n),t&&t>n?(t-=n,r=r===Z?" ":r+"",n=Ke(r,Iu(t/F(r))), +En.test(r)?n.match(kn).slice(0,t).join(""):n.slice(0,t)):""}function dr(n,t,e,u){function o(){for(var t=-1,c=arguments.length,a=-1,l=u.length,s=Array(l+c),h=this&&this!==Gn&&this instanceof o?f:n;++at?1:-1:Ue(e)||0;var u=-1;r=Cu(Iu((r-t)/(e||1)),0);for(var o=Array(r);r--;)o[n?r:++u]=t, +t+=e;return o}}function br(n,t,r,e,u,o,i,f,c,a){var l=8&t;f=f?Xt(f):Z;var s=l?i:Z;i=l?Z:i;var h=l?o:Z;return o=l?Z:o,t=(t|(l?32:64))&~(l?64:32),4&t||(t&=-4),t=[n,t,u,h,s,o,i,f,c,a],r=r.apply(Z,t),$r(n)&&oo(r,t),r.placeholder=e,r}function xr(n){var t=eu[n];return function(n,r){if(n=Ue(n),r=Be(r)){var e=(Me(n)+"e").split("e"),e=t(e[0]+"e"+(+e[1]+r)),e=(Me(e)+"e").split("e");return+(e[0]+"e"+(+e[1]-r))}return t(n)}}function jr(n,t,r,e,u,o,i,f){var c=2&t;if(!c&&typeof n!="function")throw new ou("Expected a function"); +var a=e?e.length:0;if(a||(t&=-97,e=u=Z),i=i===Z?i:Cu(Be(i),0),f=f===Z?f:Be(f),a-=u?u.length:0,64&t){var l=e,s=u;e=u=Z}var h=c?Z:ro(n);return o=[n,t,r,e,u,l,s,o,i,f],h&&(r=o[1],n=h[1],t=r|n,e=128==n&&8==r||128==n&&256==r&&h[8]>=o[7].length||384==n&&h[8]>=h[7].length&&8==r,131>t||e)&&(1&n&&(o[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=o[3],o[3]=e?Ht(e,r,h[4]):Xt(r),o[4]=e?L(o[3],"__lodash_placeholder__"):Xt(h[4])),(r=h[5])&&(e=o[5],o[5]=e?Qt(e,r,h[6]):Xt(r),o[6]=e?L(o[5],"__lodash_placeholder__"):Xt(h[6])),(r=h[7])&&(o[7]=Xt(r)), +128&n&&(o[8]=null==o[8]?h[8]:Uu(o[8],h[8])),null==o[9]&&(o[9]=h[9]),o[0]=h[0],o[1]=t),n=o[0],t=o[1],r=o[2],e=o[3],u=o[4],f=o[9]=null==o[9]?c?0:n.length:Cu(o[9]-a,0),!f&&24&t&&(t&=-25),(h?no:oo)(t&&1!=t?8==t||16==t?sr(n,t,f):32!=t&&33!=t||u.length?pr.apply(Z,o):dr(n,t,r,e):fr(n,t,r),o)}function mr(n,t,r,e,u,o){var i=-1,f=2&u,c=1&u,a=n.length,l=t.length;if(!(a==l||f&&l>a))return false;if(l=o.get(n))return l==t;for(l=true,o.set(n,t);++it?0:t,e)):[]}function Tr(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:Be(t),t=e-t,Ft(n,0,0>t?0:t)):[]}function Kr(n){return n?n[0]:Z}function Gr(n){ +var t=n?n.length:0;return t?n[t-1]:Z}function Vr(n,t){return n&&n.length&&t&&t.length?zt(n,t):n}function Jr(n){return n?Lu.call(n):n}function Yr(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){return ve(n)?(t=Cu(n.length,t),true):void 0}),j(t,function(t){return a(n,Ct(t))})}function Hr(n,t){if(!n||!n.length)return[];var e=Yr(n);return null==t?e:a(e,function(n){return r(t,Z,n)})}function Qr(n){return n=yn(n),n.__chain__=true,n}function Xr(n,t){return t(n)}function ne(){return this}function te(n,t){ +return typeof t=="function"&&Do(n)?u(n,t):Yu(n,tt(t))}function re(n,t){var r;if(typeof t=="function"&&Do(n)){for(r=n.length;r--&&false!==t(n[r],r,n););r=n}else r=Hu(n,tt(t));return r}function ee(n,t){return(Do(n)?a:kt)(n,kr(t,3))}function ue(n,t){var r=-1,e=We(n),u=e.length,o=u-1;for(t=et(Be(t),0,u);++r=n&&(t=Z),r}}function fe(n,t,r){return t=r?Z:t,n=jr(n,8,Z,Z,Z,Z,Z,t),n.placeholder=yn.placeholder||fe.placeholder,n}function ce(n,t,r){return t=r?Z:t,n=jr(n,16,Z,Z,Z,Z,Z,t),n.placeholder=yn.placeholder||ce.placeholder,n}function ae(n,t,r){function e(){p&&bu(p),a&&bu(a),g=0,c=a=h=p=_=Z}function u(t,r){r&&bu(r),a=p=_=Z,t&&(g=Bo(),l=n.apply(h,c),p||a||(c=h=Z))}function o(){var n=t-(Bo()-s);0>=n||n>t?u(_,a):p=ku(o,n)}function i(){u(y,p); +}function f(){if(c=arguments,s=Bo(),h=this,_=y&&(p||!v),false===d)var r=v&&!p;else{g||a||v||(g=s);var e=d-(s-g),u=(0>=e||e>d)&&(v||a);u?(a&&(a=bu(a)),g=s,l=n.apply(h,c)):a||(a=ku(i,e))}return u&&p?p=bu(p):p||t===d||(p=ku(o,t)),r&&(u=true,l=n.apply(h,c)),!u||p||a||(c=h=Z),l}var c,a,l,s,h,p,_,g=0,v=false,d=false,y=true;if(typeof n!="function")throw new ou("Expected a function");return t=Ue(t)||0,je(r)&&(v=!!r.leading,d="maxWait"in r&&Cu(Ue(r.maxWait)||0,t),y="trailing"in r?!!r.trailing:y),f.cancel=e,f.flush=function(){ +return(p&&_||a&&y)&&(l=n.apply(h,c)),e(),l},f}function le(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],o=r.cache;return o.has(u)?o.get(u):(e=n.apply(this,e),r.cache=o.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new ou("Expected a function");return r.cache=new le.Cache,r}function se(n,t){if(typeof n!="function")throw new ou("Expected a function");return t=Cu(t===Z?n.length-1:Be(t),0),function(){for(var e=arguments,u=-1,o=Cu(e.length-t,0),i=Array(o);++ut}function _e(n){return ve(n)&&au.call(n,"callee")&&(!Ou.call(n,"callee")||"[object Arguments]"==hu.call(n))}function ge(n){return null!=n&&!(typeof n=="function"&&ye(n))&&xe(eo(n))}function ve(n){return me(n)&&ge(n)}function de(n){if(!me(n))return false;var t=n.constructor; +return"[object Error]"==hu.call(n)||typeof t=="function"&&"[object Error]"==hu.call(t.prototype)}function ye(n){return n=je(n)?hu.call(n):"","[object Function]"==n||"[object GeneratorFunction]"==n}function be(n){return typeof n=="number"&&n==Be(n)}function xe(n){return typeof n=="number"&&n>-1&&0==n%1&&9007199254740991>=n}function je(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function me(n){return!!n&&typeof n=="object"}function we(n){return null==n?false:ye(n)?_u.test(cu.call(n)):me(n)&&(C(n)?_u:vn).test(n); +}function Ae(n){return typeof n=="number"||me(n)&&"[object Number]"==hu.call(n)}function Oe(n){if(!me(n)||"[object Object]"!=hu.call(n)||C(n))return false;var t=fu;return typeof n.constructor=="function"&&(t=ju(n)),null===t?true:(n=t.constructor,typeof n=="function"&&n instanceof n&&cu.call(n)==su)}function ke(n){return je(n)&&"[object RegExp]"==hu.call(n)}function Ee(n){return typeof n=="string"||!Do(n)&&me(n)&&"[object String]"==hu.call(n)}function Ie(n){return typeof n=="symbol"||me(n)&&"[object Symbol]"==hu.call(n); +}function Se(n){return me(n)&&xe(n.length)&&!!Bn[hu.call(n)]}function Re(n,t){return t>n}function We(n){if(!n)return[];if(ge(n))return Ee(n)?n.match(kn):Xt(n);if(wu&&n[wu])return z(n[wu]());var t=Sr(n);return("[object Map]"==t?M:"[object Set]"==t?$:qe)(n)}function Be(n){if(!n)return 0===n?n:0;if(n=Ue(n),n===q||n===-q)return 1.7976931348623157e308*(0>n?-1:1);var t=n%1;return n===n?t?n-t:n:0}function Ce(n){return n?et(Be(n),0,4294967295):0}function Ue(n){if(je(n)&&(n=ye(n.valueOf)?n.valueOf():n,n=je(n)?n+"":n), +typeof n!="string")return 0===n?n:+n;n=n.replace(fn,"");var t=gn.test(n);return t||dn.test(n)?Nn(n.slice(2),t?2:8):_n.test(n)?P:+n}function ze(n){return nr(n,De(n))}function Me(n){if(typeof n=="string")return n;if(null==n)return"";if(Ie(n))return du?Vu.call(n):"";var t=n+"";return"0"==t&&1/n==-q?"-0":t}function Le(n,t,r){return n=null==n?Z:vt(n,t),n===Z?r:n}function $e(n,t){return Rr(n,t,dt)}function Fe(n,t){return Rr(n,t,yt)}function Ne(n){var t=Fr(n);if(!t&&!ge(n))return Bu(Object(n));var r,e=Ur(n),u=!!e,e=e||[],o=e.length; +for(r in n)!dt(n,r)||u&&("length"==r||U(r,o))||t&&"constructor"==r||e.push(r);return e}function De(n){for(var t=-1,r=Fr(n),e=Ot(n),u=e.length,o=Ur(n),i=!!o,o=o||[],f=o.length;++tt||t>9007199254740991)return r; +do t%2&&(r+=n),t=Su(t/2),n+=n;while(t);return r}function Ge(n,t,r){return n=Me(n),t=r?Z:t,t===Z&&(t=Rn.test(n)?Sn:In),n.match(t)||[]}function Ve(n){return function(){return n}}function Je(n){return n}function Ye(n){return At(typeof n=="function"?n:ut(n,true))}function He(n,t,r){var e=Ne(t),o=gt(t,e);null!=r||je(t)&&(o.length||!e.length)||(r=t,t=n,n=this,o=gt(t,Ne(t)));var i=je(r)&&"chain"in r?r.chain:true,f=ye(n);return u(o,function(r){var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__; +if(i||t){var r=n(this.__wrapped__);return(r.__actions__=Xt(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,l([this.value()],arguments))})}),n}function Qe(){}function Xe(n){return Mr(n)?Ct(n):Ut(n)}function nu(n){return n&&n.length?x(n,Je):0}E=E?Vn.defaults({},E,Vn.pick(Gn,Wn)):Gn;var tu=E.Date,ru=E.Error,eu=E.Math,uu=E.RegExp,ou=E.TypeError,iu=E.Array.prototype,fu=E.Object.prototype,cu=E.Function.prototype.toString,au=fu.hasOwnProperty,lu=0,su=cu.call(Object),hu=fu.toString,pu=Gn._,_u=uu("^"+cu.call(au).replace(un,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),gu=qn?E.Buffer:Z,vu=E.Reflect,du=E.Symbol,yu=E.Uint8Array,bu=E.clearTimeout,xu=vu?vu.f:Z,ju=Object.getPrototypeOf,mu=Object.getOwnPropertySymbols,wu=typeof(wu=du&&du.iterator)=="symbol"?wu:Z,Au=Object.create,Ou=fu.propertyIsEnumerable,ku=E.setTimeout,Eu=iu.splice,Iu=eu.ceil,Su=eu.floor,Ru=E.isFinite,Wu=iu.join,Bu=Object.keys,Cu=eu.max,Uu=eu.min,zu=E.parseInt,Mu=eu.random,Lu=iu.reverse,$u=Ir(E,"Map"),Fu=Ir(E,"Set"),Nu=Ir(E,"WeakMap"),Du=Ir(Object,"create"),Zu=Nu&&new Nu,qu=$u?cu.call($u):"",Pu=Fu?cu.call(Fu):"",Tu=Nu?cu.call(Nu):"",Ku=du?du.prototype:Z,Gu=du?Ku.valueOf:Z,Vu=du?Ku.toString:Z,Ju={}; +yn.templateSettings={escape:Q,evaluate:X,interpolate:nn,variable:"",imports:{_:yn}};var Yu=or(pt),Hu=or(_t,true),Qu=ir(),Xu=ir(true);xu&&!Ou.call({valueOf:1},"valueOf")&&(Ot=function(n){return z(xu(n))});var no=Zu?function(n,t){return Zu.set(n,t),n}:Je,to=Fu&&2===new Fu([1,2]).size?function(n){return new Fu(n)}:Qe,ro=Zu?function(n){return Zu.get(n)}:Qe,eo=Ct("length"),uo=mu||function(){return[]};($u&&"[object Map]"!=Sr(new $u)||Fu&&"[object Set]"!=Sr(new Fu)||Nu&&"[object WeakMap]"!=Sr(new Nu))&&(Sr=function(n){ +var t=hu.call(n);if(n="[object Object]"==t?n.constructor:null,n=typeof n=="function"?cu.call(n):"")switch(n){case qu:return"[object Map]";case Pu:return"[object Set]";case Tu:return"[object WeakMap]"}return t});var oo=function(){var n=0,t=0;return function(r,e){var u=Bo(),o=16-(u-t);if(t=u,o>0){if(150<=++n)return r}else n=0;return no(r,e)}}(),io=se(function(n,t){Do(n)||(n=null==n?[]:[Object(n)]),t=st(t,1);for(var r=n,e=t,u=-1,o=r.length,i=-1,f=e.length,c=Array(o+f);++u1?n[t-1]:Z,t=typeof t=="function"?(n.pop(),t):Z;return Hr(n,t)}),Oo=se(function(n){function t(t){return Xn(t,n)}n=st(n,1);var r=n.length,e=r?n[0]:0,u=this.__wrapped__;return 1>=r&&!this.__actions__.length&&u instanceof An&&U(e)?(u=u.slice(e,+e+(r?1:0)),u.__actions__.push({func:Xr,args:[t],thisArg:Z}),new wn(u,this.__chain__).thru(function(n){return r&&!n.length&&n.push(Z),n})):this.thru(t)}),ko=er(function(n,t,r){au.call(n,r)?++n[r]:n[r]=1}),Eo=er(function(n,t,r){au.call(n,r)?n[r].push(t):n[r]=[t]; +}),Io=se(function(n,t,e){var u=-1,o=typeof t=="function",i=Mr(t),f=ge(n)?Array(n.length):[];return Yu(n,function(n){var c=o?t:i&&null!=n?n[t]:Z;f[++u]=c?r(c,n,e):jt(n,t,e)}),f}),So=er(function(n,t,r){n[r]=t}),Ro=er(function(n,t,r){n[r?0:1].push(t)},function(){return[[],[]]}),Wo=se(function(n,t){if(null==n)return[];var r=t.length;return r>1&&zr(n,t[0],t[1])?t=[]:r>2&&zr(t[0],t[1],t[2])&&(t.length=1),Rt(n,st(t,1),[])}),Bo=tu.now,Co=se(function(n,t,r){var e=1;if(r.length)var u=L(r,yn.placeholder||Co.placeholder),e=32|e; +return jr(n,e,t,r,u)}),Uo=se(function(n,t,r){var e=3;if(r.length)var u=L(r,yn.placeholder||Uo.placeholder),e=32|e;return jr(t,e,n,r,u)}),zo=se(function(n,t){return ft(n,1,t)}),Mo=se(function(n,t,r){return ft(n,Ue(t)||0,r)}),Lo=se(function(n,t){t=a(st(t,1),kr());var e=t.length;return se(function(u){for(var o=-1,i=Uu(u.length,e);++oe.length?Tn(e,n,t):(r.array=null,r.map=new zn(e))),(r=r.map)&&r.set(n,t),this},le.Cache=zn,yn.after=function(n,t){if(typeof t!="function")throw new ou("Expected a function");return n=Be(n),function(){return 1>--n?t.apply(this,arguments):void 0}},yn.ary=oe,yn.assign=qo,yn.assignIn=Po,yn.assignInWith=To,yn.assignWith=Ko,yn.at=Go,yn.before=ie,yn.bind=Co,yn.bindAll=hi,yn.bindKey=Uo,yn.castArray=function(){if(!arguments.length)return[]; +var n=arguments[0];return Do(n)?n:[n]},yn.chain=Qr,yn.chunk=function(n,t){t=Cu(Be(t),0);var r=n?n.length:0;if(!r||1>t)return[];for(var e=0,u=-1,o=Array(Iu(r/t));r>e;)o[++u]=Ft(n,e,e+=t);return o},yn.compact=function(n){for(var t=-1,r=n?n.length:0,e=-1,u=[];++tr&&(r=-r>u?0:u+r),e=e===Z||e>u?u:Be(e),0>e&&(e+=u),e=r>e?0:Ce(e);e>r;)n[r++]=t;return n},yn.filter=function(n,t){return(Do(n)?i:lt)(n,kr(t,3))},yn.flatMap=function(n,t){return st(ee(n,t),1)},yn.flatten=function(n){return n&&n.length?st(n,1):[]},yn.flattenDeep=function(n){return n&&n.length?st(n,q):[]},yn.flattenDepth=function(n,t){return n&&n.length?(t=t===Z?1:Be(t),st(n,t)):[]; +},yn.flip=function(n){return jr(n,512)},yn.flow=pi,yn.flowRight=_i,yn.fromPairs=function(n){for(var t=-1,r=n?n.length:0,e={};++tt?0:t)):[]},yn.takeRight=function(n,t,r){var e=n?n.length:0;return e?(t=r||t===Z?1:Be(t),t=e-t,Ft(n,0>t?0:t,e)):[]},yn.takeRightWhile=function(n,t){return n&&n.length?Tt(n,kr(t,3),false,true):[]},yn.takeWhile=function(n,t){ +return n&&n.length?Tt(n,kr(t,3)):[]},yn.tap=function(n,t){return t(n),n},yn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ou("Expected a function");return je(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ae(n,t,{leading:e,maxWait:t,trailing:u})},yn.thru=Xr,yn.toArray=We,yn.toPairs=Ze,yn.toPairsIn=function(n){return m(n,De(n))},yn.toPath=function(n){return Do(n)?a(n,String):Zr(n)},yn.toPlainObject=ze,yn.transform=function(n,t,r){var e=Do(n)||Se(n);if(t=kr(t,4), +null==r)if(e||je(n)){var o=n.constructor;r=e?Do(n)?new o:[]:it(ye(o)?o.prototype:Z)}else r={};return(e?u:pt)(n,function(n,e,u){return t(r,n,e,u)}),r},yn.unary=function(n){return oe(n,1)},yn.union=go,yn.unionBy=vo,yn.unionWith=yo,yn.uniq=function(n){return n&&n.length?Pt(n):[]},yn.uniqBy=function(n,t){return n&&n.length?Pt(n,kr(t)):[]},yn.uniqWith=function(n,t){return n&&n.length?Pt(n,Z,t):[]},yn.unset=function(n,t){var r;if(null==n)r=true;else{r=n;var e=t,e=Mr(e,r)?[e+""]:rt(e);r=Dr(r,e),e=Gr(e),r=null!=r&&$e(r,e)?delete r[e]:true; +}return r},yn.unzip=Yr,yn.unzipWith=Hr,yn.values=qe,yn.valuesIn=function(n){return null==n?[]:A(n,De(n))},yn.without=bo,yn.words=Ge,yn.wrap=function(n,t){return t=null==t?Je:t,$o(t,n)},yn.xor=xo,yn.xorBy=jo,yn.xorWith=mo,yn.zip=wo,yn.zipObject=function(n,t){return Vt(n||[],t||[],Yn)},yn.zipObjectDeep=function(n,t){return Vt(n||[],t||[],$t)},yn.zipWith=Ao,yn.extend=Po,yn.extendWith=To,He(yn,yn),yn.add=function(n,t){var r;return n===Z&&t===Z?0:(n!==Z&&(r=n),t!==Z&&(r=r===Z?t:r+t),r)},yn.attempt=si, +yn.camelCase=ei,yn.capitalize=Pe,yn.ceil=mi,yn.clamp=function(n,t,r){return r===Z&&(r=t,t=Z),r!==Z&&(r=Ue(r),r=r===r?r:0),t!==Z&&(t=Ue(t),t=t===t?t:0),et(Ue(n),t,r)},yn.clone=function(n){return ut(n)},yn.cloneDeep=function(n){return ut(n,true)},yn.cloneDeepWith=function(n,t){return ut(n,true,t)},yn.cloneWith=function(n,t){return ut(n,false,t)},yn.deburr=Te,yn.endsWith=function(n,t,r){n=Me(n),t=typeof t=="string"?t:t+"";var e=n.length;return r=r===Z?e:et(Be(r),0,e),r-=t.length,r>=0&&n.indexOf(t,r)==r},yn.eq=he, +yn.escape=function(n){return(n=Me(n))&&H.test(n)?n.replace(J,R):n},yn.escapeRegExp=function(n){return(n=Me(n))&&on.test(n)?n.replace(un,"\\$&"):n},yn.every=function(n,t,r){var e=Do(n)?o:at;return r&&zr(n,t,r)&&(t=Z),e(n,kr(t,3))},yn.find=function(n,t){if(t=kr(t,3),Do(n)){var r=v(n,t);return r>-1?n[r]:Z}return g(n,t,Yu)},yn.findIndex=function(n,t){return n&&n.length?v(n,kr(t,3)):-1},yn.findKey=function(n,t){return g(n,kr(t,3),pt,true)},yn.findLast=function(n,t){if(t=kr(t,3),Do(n)){var r=v(n,t,true);return r>-1?n[r]:Z; +}return g(n,t,Hu)},yn.findLastIndex=function(n,t){return n&&n.length?v(n,kr(t,3),true):-1},yn.findLastKey=function(n,t){return g(n,kr(t,3),_t,true)},yn.floor=wi,yn.forEach=te,yn.forEachRight=re,yn.forIn=function(n,t){return null==n?n:Qu(n,tt(t),De)},yn.forInRight=function(n,t){return null==n?n:Xu(n,tt(t),De)},yn.forOwn=function(n,t){return n&&pt(n,tt(t))},yn.forOwnRight=function(n,t){return n&&_t(n,tt(t))},yn.get=Le,yn.gt=pe,yn.gte=function(n,t){return n>=t},yn.has=$e,yn.hasIn=Fe,yn.head=Kr,yn.identity=Je, +yn.includes=function(n,t,r,e){return n=ge(n)?n:qe(n),r=r&&!e?Be(r):0,e=n.length,0>r&&(r=Cu(e+r,0)),Ee(n)?e>=r&&-1r&&(r=Cu(e+r,0)),d(n,t,r)):-1},yn.inRange=function(n,t,r){return t=Ue(t)||0,r===Z?(r=t,t=0):r=Ue(r)||0,n=Ue(n),n>=Uu(t,r)&&n=-9007199254740991&&9007199254740991>=n},yn.isSet=function(n){return me(n)&&"[object Set]"==Sr(n)},yn.isString=Ee,yn.isSymbol=Ie,yn.isTypedArray=Se,yn.isUndefined=function(n){return n===Z},yn.isWeakMap=function(n){return me(n)&&"[object WeakMap]"==Sr(n)},yn.isWeakSet=function(n){return me(n)&&"[object WeakSet]"==hu.call(n)},yn.join=function(n,t){return n?Wu.call(n,t):""},yn.kebabCase=ui,yn.last=Gr,yn.lastIndexOf=function(n,t,r){var e=n?n.length:0; +if(!e)return-1;var u=e;if(r!==Z&&(u=Be(r),u=(0>u?Cu(e+u,0):Uu(u,e-1))+1),t!==t)return B(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},yn.lowerCase=oi,yn.lowerFirst=ii,yn.lt=Re,yn.lte=function(n,t){return t>=n},yn.max=function(n){return n&&n.length?_(n,Je,pe):Z},yn.maxBy=function(n,t){return n&&n.length?_(n,kr(t),pe):Z},yn.mean=function(n){return nu(n)/(n?n.length:0)},yn.min=function(n){return n&&n.length?_(n,Je,Re):Z},yn.minBy=function(n,t){return n&&n.length?_(n,kr(t),Re):Z},yn.noConflict=function(){ +return Gn._===this&&(Gn._=pu),this},yn.noop=Qe,yn.now=Bo,yn.pad=function(n,t,r){n=Me(n),t=Be(t);var e=F(n);return t&&t>e?(e=(t-e)/2,t=Su(e),e=Iu(e),vr("",t,r)+n+vr("",e,r)):n},yn.padEnd=function(n,t,r){return n=Me(n),n+vr(n,t,r)},yn.padStart=function(n,t,r){return n=Me(n),vr(n,t,r)+n},yn.parseInt=function(n,t,r){return r||null==t?t=0:t&&(t=+t),n=Me(n).replace(fn,""),zu(n,t||(pn.test(n)?16:10))},yn.random=function(n,t,r){if(r&&typeof r!="boolean"&&zr(n,t,r)&&(t=r=Z),r===Z&&(typeof t=="boolean"?(r=t, +t=Z):typeof n=="boolean"&&(r=n,n=Z)),n===Z&&t===Z?(n=0,t=1):(n=Ue(n)||0,t===Z?(t=n,n=0):t=Ue(t)||0),n>t){var e=n;n=t,t=e}return r||n%1||t%1?(r=Mu(),Uu(n+r*(t-n+Fn("1e-"+((r+"").length-1))),t)):Lt(n,t)},yn.reduce=function(n,t,r){var e=Do(n)?s:y,u=3>arguments.length;return e(n,kr(t,4),r,u,Yu)},yn.reduceRight=function(n,t,r){var e=Do(n)?h:y,u=3>arguments.length;return e(n,kr(t,4),r,u,Hu)},yn.repeat=Ke,yn.replace=function(){var n=arguments,t=Me(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},yn.result=function(n,t,r){ +if(Mr(t,n))e=null==n?Z:n[t];else{t=rt(t);var e=Le(n,t);n=Dr(n,t)}return e===Z&&(e=r),ye(e)?e.call(n):e},yn.round=Ai,yn.runInContext=D,yn.sample=function(n){n=ge(n)?n:qe(n);var t=n.length;return t>0?n[Lt(0,t-1)]:Z},yn.size=function(n){if(null==n)return 0;if(ge(n)){var t=n.length;return t&&Ee(n)?F(n):t}return Ne(n).length},yn.snakeCase=ci,yn.some=function(n,t,r){var e=Do(n)?p:Nt;return r&&zr(n,t,r)&&(t=Z),e(n,kr(t,3))},yn.sortedIndex=function(n,t){return Dt(n,t)},yn.sortedIndexBy=function(n,t,r){return Zt(n,t,kr(r)); +},yn.sortedIndexOf=function(n,t){var r=n?n.length:0;if(r){var e=Dt(n,t);if(r>e&&he(n[e],t))return e}return-1},yn.sortedLastIndex=function(n,t){return Dt(n,t,true)},yn.sortedLastIndexBy=function(n,t,r){return Zt(n,t,kr(r),true)},yn.sortedLastIndexOf=function(n,t){if(n&&n.length){var r=Dt(n,t,true)-1;if(he(n[r],t))return r}return-1},yn.startCase=ai,yn.startsWith=function(n,t,r){return n=Me(n),r=et(Be(r),0,n.length),n.lastIndexOf(t,r)==r},yn.subtract=function(n,t){var r;return n===Z&&t===Z?0:(n!==Z&&(r=n), +t!==Z&&(r=r===Z?t:r-t),r)},yn.sum=nu,yn.sumBy=function(n,t){return n&&n.length?x(n,kr(t)):0},yn.template=function(n,t,r){var e=yn.templateSettings;r&&zr(n,t,r)&&(t=Z),n=Me(n),t=To({},t,e,Kn),r=To({},t.imports,e.imports,Kn);var u,o,i=Ne(r),f=A(r,i),c=0;r=t.interpolate||xn;var a="__p+='";r=uu((t.escape||xn).source+"|"+r.source+"|"+(r===nn?sn:xn).source+"|"+(t.evaluate||xn).source+"|$","g");var l="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,i,f,l){return e||(e=i), +a+=n.slice(c,l).replace(jn,W),r&&(u=true,a+="'+__e("+r+")+'"),f&&(o=true,a+="';"+f+";\n__p+='"),e&&(a+="'+((__t=("+e+"))==null?'':__t)+'"),c=l+t.length,t}),a+="';",(t=t.variable)||(a="with(obj){"+a+"}"),a=(o?a.replace(T,""):a).replace(K,"$1").replace(G,"$1;"),a="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(u?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+a+"return __p}",t=si(function(){return Function(i,l+"return "+a).apply(Z,f); +}),t.source=a,de(t))throw t;return t},yn.times=function(n,t){if(n=Be(n),1>n||n>9007199254740991)return[];var r=4294967295,e=Uu(n,4294967295);for(t=tt(t),n-=4294967295,e=j(e,t);++r=o)return n;if(o=r-F(e),1>o)return e;if(r=i?i.slice(0,o).join(""):n.slice(0,o),u===Z)return r+e;if(i&&(o+=r.length-o),ke(u)){if(n.slice(o).search(u)){var f=r;for(u.global||(u=uu(u.source,Me(hn.exec(u))+"g")),u.lastIndex=0;i=u.exec(f);)var c=i.index;r=r.slice(0,c===Z?o:c)}}else n.indexOf(u,o)!=o&&(u=r.lastIndexOf(u),u>-1&&(r=r.slice(0,u)));return r+e},yn.unescape=function(n){return(n=Me(n))&&Y.test(n)?n.replace(V,N):n},yn.uniqueId=function(n){var t=++lu;return Me(n)+t},yn.upperCase=li,yn.upperFirst=fi, +yn.each=te,yn.eachRight=re,yn.first=Kr,He(yn,function(){var n={};return pt(yn,function(t,r){au.call(yn.prototype,r)||(n[r]=t)}),n}(),{chain:false}),yn.VERSION="4.4.0",u("bind bindKey curry curryRight partial partialRight".split(" "),function(n){yn[n].placeholder=yn}),u(["drop","take"],function(n,t){An.prototype[n]=function(r){var e=this.__filtered__;if(e&&!t)return new An(this);r=r===Z?1:Cu(Be(r),0);var u=this.clone();return e?u.__takeCount__=Uu(r,u.__takeCount__):u.__views__.push({size:Uu(r,4294967295), +type:n+(0>u.__dir__?"Right":"")}),u},An.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),u(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;An.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({iteratee:kr(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),u(["head","last"],function(n,t){var r="take"+(t?"Right":"");An.prototype[n]=function(){return this[r](1).value()[0]}}),u(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right"); +An.prototype[n]=function(){return this.__filtered__?new An(this):this[r](1)}}),An.prototype.compact=function(){return this.filter(Je)},An.prototype.find=function(n){return this.filter(n).head()},An.prototype.findLast=function(n){return this.reverse().find(n)},An.prototype.invokeMap=se(function(n,t){return typeof n=="function"?new An(this):this.map(function(r){return jt(r,n,t)})}),An.prototype.reject=function(n){return n=kr(n,3),this.filter(function(t){return!n(t)})},An.prototype.slice=function(n,t){ +n=Be(n);var r=this;return r.__filtered__&&(n>0||0>t)?new An(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==Z&&(t=Be(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},An.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},An.prototype.toArray=function(){return this.take(4294967295)},pt(An.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=yn[e?"take"+("last"==t?"Right":""):t],o=e||/^find/.test(t);u&&(yn.prototype[t]=function(){ +function t(n){return n=u.apply(yn,l([n],f)),e&&h?n[0]:n}var i=this.__wrapped__,f=e?[1]:arguments,c=i instanceof An,a=f[0],s=c||Do(i);s&&r&&typeof a=="function"&&1!=a.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,a=o&&!h,c=c&&!p;return!o&&s?(i=c?i:new An(this),i=n.apply(i,f),i.__actions__.push({func:Xr,args:[t],thisArg:Z}),new wn(i,h)):a&&c?n.apply(this,f):(i=this.thru(t),a?e?i.value()[0]:i.value():i)})}),u("pop push shift sort splice unshift".split(" "),function(n){var t=iu[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n); +yn.prototype[n]=function(){var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),pt(An.prototype,function(n,t){var r=yn[t];if(r){var e=r.name+"";(Ju[e]||(Ju[e]=[])).push({name:t,func:r})}}),Ju[pr(Z,2).name]=[{name:"wrapper",func:Z}],An.prototype.clone=function(){var n=new An(this.__wrapped__);return n.__actions__=Xt(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Xt(this.__iteratees__),n.__takeCount__=this.__takeCount__, +n.__views__=Xt(this.__views__),n},An.prototype.reverse=function(){if(this.__filtered__){var n=new An(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},An.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=Do(t),u=0>r,o=e?t.length:0;n=o;for(var i=this.__views__,f=0,c=-1,a=i.length;++co||o==n&&a==n)return Kt(t,this.__actions__);e=[];n:for(;n--&&a>c;){for(u+=r,o=-1,l=t[u];++o=this.__values__.length,t=n?Z:this.__values__[this.__index__++];return{done:n,value:t}},yn.prototype.plant=function(n){for(var t,r=this;r instanceof mn;){var e=qr(r);e.__index__=0,e.__values__=Z,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},yn.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof An?(this.__actions__.length&&(n=new An(this)),n=n.reverse(), +n.__actions__.push({func:Xr,args:[Jr],thisArg:Z}),new wn(n,this.__chain__)):this.thru(Jr)},yn.prototype.toJSON=yn.prototype.valueOf=yn.prototype.value=function(){return Kt(this.__wrapped__,this.__actions__)},wu&&(yn.prototype[wu]=ne),yn}var Z,q=1/0,P=NaN,T=/\b__p\+='';/g,K=/\b(__p\+=)''\+/g,G=/(__e\(.*?\)|\b__t\))\+'';/g,V=/&(?:amp|lt|gt|quot|#39|#96);/g,J=/[&<>"'`]/g,Y=RegExp(V.source),H=RegExp(J.source),Q=/<%-([\s\S]+?)%>/g,X=/<%([\s\S]+?)%>/g,nn=/<%=([\s\S]+?)%>/g,tn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,rn=/^\w*$/,en=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g,un=/[\\^$.*+?()[\]{}|]/g,on=RegExp(un.source),fn=/^\s+|\s+$/g,cn=/^\s+/,an=/\s+$/,ln=/\\(\\)?/g,sn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,hn=/\w*$/,pn=/^0x/i,_n=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,vn=/^\[object .+?Constructor\]$/,dn=/^0o[0-7]+$/i,yn=/^(?:0|[1-9]\d*)$/,bn=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,xn=/($^)/,jn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|\\ud83c[\\udffb-\\udfff])?)*",wn="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,An="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]?|[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",On=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0]","g"),kn=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+An+mn,"g"),En=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe23\\u20d0-\\u20f0\\ufe0e\\ufe0f]"),In=/[a-zA-Z0-9]+/g,Sn=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2018\\u2019\\u201c\\u201d \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|\\d+",wn].join("|"),"g"),Rn=/[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Reflect RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={}; Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false; var Cn={};Cn["[object Arguments]"]=Cn["[object Array]"]=Cn["[object ArrayBuffer]"]=Cn["[object Boolean]"]=Cn["[object Date]"]=Cn["[object Float32Array]"]=Cn["[object Float64Array]"]=Cn["[object Int8Array]"]=Cn["[object Int16Array]"]=Cn["[object Int32Array]"]=Cn["[object Map]"]=Cn["[object Number]"]=Cn["[object Object]"]=Cn["[object RegExp]"]=Cn["[object Set]"]=Cn["[object String]"]=Cn["[object Symbol]"]=Cn["[object Uint8Array]"]=Cn["[object Uint8ClampedArray]"]=Cn["[object Uint16Array]"]=Cn["[object Uint32Array]"]=true, Cn["[object Error]"]=Cn["[object Function]"]=Cn["[object WeakMap]"]=false;var Un={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O", "\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},zn={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},Mn={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Ln={"function":true,object:true},$n={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029" -},Fn=parseFloat,Nn=parseInt,Dn=Ln[typeof exports]&&exports&&!exports.nodeType?exports:null,Zn=Ln[typeof module]&&module&&!module.nodeType?module:null,qn=E(Dn&&Zn&&typeof global=="object"&&global),Pn=E(Ln[typeof self]&&self),Tn=E(Ln[typeof window]&&window),Kn=Zn&&Zn.exports===Dn?Dn:null,Gn=E(Ln[typeof this]&&this),Vn=qn||Tn!==(Gn&&Gn.window)&&Tn||Pn||Gn||Function("return this")(),Jn=D();(Tn||Pn||{})._=Jn,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){return Jn; -}):Dn&&Zn?(Kn&&((Zn.exports=Jn)._=Jn),Dn._=Jn):Vn._=Jn}).call(this); \ No newline at end of file +},Fn=parseFloat,Nn=parseInt,Dn=Ln[typeof exports]&&exports&&!exports.nodeType?exports:Z,Zn=Ln[typeof module]&&module&&!module.nodeType?module:Z,qn=Zn&&Zn.exports===Dn?Dn:Z,Pn=E(Ln[typeof self]&&self),Tn=E(Ln[typeof window]&&window),Kn=E(Ln[typeof this]&&this),Gn=E(Dn&&Zn&&typeof global=="object"&&global)||Tn!==(Kn&&Kn.window)&&Tn||Pn||Kn||Function("return this")(),Vn=D();(Tn||Pn||{})._=Vn,typeof define=="function"&&typeof define.amd=="object"&&define.amd? define(function(){return Vn}):Dn&&Zn?(qn&&((Zn.exports=Vn)._=Vn), +Dn._=Vn):Gn._=Vn}).call(this); \ No newline at end of file diff --git a/dist/mapping.fp.js b/dist/mapping.fp.js index d012b2e30a..587dd7457c 100644 --- a/dist/mapping.fp.js +++ b/dist/mapping.fp.js @@ -94,55 +94,52 @@ return /******/ (function(modules) { // webpackBootstrap /** Used to map ary to method names. */ exports.aryMethod = { - 1: [ - 'attempt', 'ceil', 'create', 'curry', 'curryRight', 'floor', 'fromPairs', - 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', 'over', - 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', - 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' - ], - 2: [ - 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', - 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', - 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', - 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', - 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', - 'findLastKey', 'flatMap', 'forEach', 'forEachRight', 'forIn', 'forInRight', - 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', 'hasIn', - 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', - 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', - 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', - 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', - 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', - 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', - 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', - 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', - 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', - 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', - 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', - 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' - ], - 3: [ - 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', - 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', - 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace', - 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', - 'unionWith', 'xorBy', 'xorWith', 'zipWith' - ], - 4: [ - 'fill', 'setWith' - ] + '1': [ + 'attempt', 'castArray', 'ceil', 'create', 'curry', 'curryRight', 'floor', + 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', + 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', + 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' + ], + '2': [ + 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', + 'chunk', 'cloneDeepWith', 'cloneWith', 'concat', 'countBy', 'curryN', + 'curryRightN', 'debounce', 'defaults', 'defaultsDeep', 'delay', 'difference', + 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'endsWith', 'eq', 'every', + 'filter', 'find', 'find', 'findIndex', 'findKey', 'findLast', 'findLastIndex', + 'findLastKey', 'flatMap', 'flattenDepth', 'forEach', 'forEachRight', 'forIn', + 'forInRight', 'forOwn', 'forOwnRight', 'get', 'groupBy', 'gt', 'gte', 'has', + 'hasIn', 'includes', 'indexOf', 'intersection', 'invertBy', 'invoke', 'invokeMap', + 'isEqual', 'isMatch', 'join', 'keyBy', 'lastIndexOf', 'lt', 'lte', 'map', + 'mapKeys', 'mapValues', 'matchesProperty', 'maxBy', 'merge', 'minBy', 'omit', + 'omitBy', 'orderBy', 'overArgs', 'pad', 'padEnd', 'padStart', 'parseInt', + 'partial', 'partialRight', 'partition', 'pick', 'pickBy', 'pull', 'pullAll', + 'pullAt', 'random', 'range', 'rangeRight', 'rearg', 'reject', 'remove', + 'repeat', 'result', 'sampleSize', 'some', 'sortBy', 'sortedIndex', + 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexOf', 'sortedUniqBy', + 'split', 'startsWith', 'subtract', 'sumBy', 'take', 'takeRight', 'takeRightWhile', + 'takeWhile', 'tap', 'throttle', 'thru', 'times', 'trimChars', 'trimCharsEnd', + 'trimCharsStart', 'truncate', 'union', 'uniqBy', 'uniqWith', 'unset', + 'unzipWith', 'without', 'wrap', 'xor', 'zip', 'zipObject', 'zipObjectDeep' + ], + '3': [ + 'assignInWith', 'assignWith', 'clamp', 'differenceBy', 'differenceWith', + 'getOr', 'inRange', 'intersectionBy', 'intersectionWith', 'isEqualWith', + 'isMatchWith', 'mergeWith', 'pullAllBy', 'reduce', 'reduceRight', 'replace', + 'set', 'slice', 'sortedIndexBy', 'sortedLastIndexBy', 'transform', 'unionBy', + 'unionWith', 'xorBy', 'xorWith', 'zipWith' + ], + '4': [ + 'fill', 'setWith' + ] }; /** Used to map ary to rearg configs. */ exports.aryRearg = { - 2: [1, 0], - 3: [2, 1, 0], - 4: [3, 2, 0, 1] + '2': [1, 0], + '3': [2, 0, 1], + '4': [3, 2, 0, 1] }; - /** Used to iterate `mapping.aryMethod` keys. */ - exports.caps = [1, 2, 3, 4]; - /** Used to map method names to their iteratee ary. */ exports.iterateeAry = { 'assignWith': 2, @@ -183,25 +180,18 @@ return /******/ (function(modules) { // webpackBootstrap 'transform': 2 }; - /** Used to map method names to iteratee rearg configs. */ - exports.iterateeRearg = { - 'findKey': [1], - 'findLastKey': [1], - 'mapKeys': [1] - }; - /** Used to map method names to rearg configs. */ exports.methodRearg = { 'assignInWith': [1, 2, 0], 'assignWith': [1, 2, 0], - 'clamp': [2, 0, 1], + 'getOr': [2, 1, 0], + 'isMatchWith': [2, 1, 0], 'mergeWith': [1, 2, 0], - 'reduce': [2, 0, 1], - 'reduceRight': [2, 0, 1], - 'set': [2, 0, 1], + 'pullAllBy': [2, 1, 0], 'setWith': [3, 1, 2, 0], - 'slice': [2, 0, 1], - 'transform': [2, 0, 1] + 'sortedIndexBy': [2, 1, 0], + 'sortedLastIndexBy': [2, 1, 0], + 'zipWith': [1, 2, 0] }; /** Used to map method names to spread configs. */ @@ -266,7 +256,7 @@ return /******/ (function(modules) { // webpackBootstrap }()); /** Used to map method names to other names. */ - exports.rename = { + exports.remap = { 'curryN': 'curry', 'curryRightN': 'curryRight', 'getOr': 'get', diff --git a/doc/README.md b/doc/README.md index 86924f0193..d1ea901fc1 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,4 +1,4 @@ -# lodash v4.3.0 +# lodash v4.4.0 @@ -21,6 +21,7 @@ * `_.first` -> `head` * `_.flatten` * `_.flattenDeep` +* `_.flattenDepth` * `_.fromPairs` * `_.head` * `_.indexOf` @@ -134,13 +135,14 @@ * `_.spread` * `_.throttle` * `_.unary` -* `_.wrap` +* `_.wrap` ## `Lang` +* `_.castArray` * `_.clone` * `_.cloneDeep` * `_.cloneDeepWith` @@ -309,7 +311,7 @@ * `_.pad` * `_.padEnd` * `_.padStart` -* `_.parseInt` +* `_.parseInt` * `_.repeat` * `_.replace` * `_.snakeCase` @@ -322,7 +324,7 @@ * `_.trim` * `_.trimEnd` * `_.trimStart` -* `_.truncate` +* `_.truncate` * `_.unescape` * `_.upperCase` * `_.upperFirst` @@ -372,18 +374,12 @@ * `_.templateSettings.escape` * `_.templateSettings.evaluate` * `_.templateSettings.imports` +* `_.templateSettings.imports._` * `_.templateSettings.interpolate` * `_.templateSettings.variable` - - -## `Methods` -* `_.templateSettings.imports._` - - - @@ -395,7 +391,7 @@ ### `_.chunk(array, [size=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5385 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.chunk "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5435 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.chunk "See the npm package") Creates an array of elements split into groups the length of `size`. If `array` can't be split evenly, the final chunk will be the remaining @@ -423,7 +419,7 @@ _.chunk(['a', 'b', 'c', 'd'], 3); ### `_.compact(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5416 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.compact "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5466 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.compact "See the npm package") Creates an array with all falsey values removed. The values `false`, `null`, `0`, `""`, `undefined`, and `NaN` are falsey. @@ -446,7 +442,7 @@ _.compact([0, 1, false, 2, '', 3]); ### `_.concat(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5452 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.concat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5502 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.concat "See the npm package") Creates a new array concatenating `array` with any additional arrays and/or values. @@ -476,7 +472,7 @@ console.log(array); ### `_.difference(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5476 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.difference "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5526 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.difference "See the npm package") Creates an array of unique `array` values not included in the other given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -501,7 +497,7 @@ _.difference([3, 2, 1], [4, 2]); ### `_.differenceBy(array, [values], [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5503 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.differenceby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5553 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.differenceby "See the npm package") This method is like `_.difference` except that it accepts `iteratee` which is invoked for each element of `array` and `values` to generate the criterion @@ -531,7 +527,7 @@ _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); ### `_.differenceWith(array, [values], [comparator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5532 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.differencewith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5582 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.differencewith "See the npm package") This method is like `_.difference` except that it accepts `comparator` which is invoked to compare elements of `array` to `values`. The comparator @@ -559,7 +555,7 @@ _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); ### `_.drop(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5566 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.drop "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5616 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.drop "See the npm package") Creates a slice of `array` with `n` elements dropped from the beginning. @@ -591,7 +587,7 @@ _.drop([1, 2, 3], 0); ### `_.dropRight(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5599 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5649 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropright "See the npm package") Creates a slice of `array` with `n` elements dropped from the end. @@ -623,7 +619,7 @@ _.dropRight([1, 2, 3], 0); ### `_.dropRightWhile(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5643 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5693 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.droprightwhile "See the npm package") Creates a slice of `array` excluding elements dropped from the end. Elements are dropped until `predicate` returns falsey. The predicate is @@ -666,7 +662,7 @@ _.dropRightWhile(users, 'active'); ### `_.dropWhile(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5683 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5733 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.dropwhile "See the npm package") Creates a slice of `array` excluding elements dropped from the beginning. Elements are dropped until `predicate` returns falsey. The predicate is @@ -709,7 +705,7 @@ _.dropWhile(users, 'active'); ### `_.fill(array, value, [start=0], [end=array.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5717 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.fill "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5767 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.fill "See the npm package") Fills elements of `array` with `value` from `start` up to, but not including, `end`. @@ -747,7 +743,7 @@ _.fill([4, 6, 8, 10], '*', 1, 3); ### `_.findIndex(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5762 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5812 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findindex "See the npm package") This method is like `_.find` except that it returns the index of the first element `predicate` returns truthy for instead of the element itself. @@ -789,7 +785,7 @@ _.findIndex(users, 'active'); ### `_.findLastIndex(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5801 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5851 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastindex "See the npm package") This method is like `_.findIndex` except that it iterates over elements of `collection` from right to left. @@ -831,9 +827,9 @@ _.findLastIndex(users, 'active'); ### `_.flatten(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5820 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatten "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5870 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatten "See the npm package") -Flattens `array` a single level. +Flattens `array` a single level deep. #### Arguments 1. `array` *(Array)*: The array to flatten. @@ -843,8 +839,8 @@ Flattens `array` a single level. #### Example ```js -_.flatten([1, [2, 3, [4]]]); -// => [1, 2, 3, [4]] +_.flatten([1, [2, [3, [4]], 5]]); +// => [1, 2, [3, [4]], 5] ``` * * * @@ -853,20 +849,48 @@ _.flatten([1, [2, 3, [4]]]); ### `_.flattenDeep(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5838 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5888 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendeep "See the npm package") -This method is like `_.flatten` except that it recursively flattens `array`. +Recursively flattens `array`. #### Arguments -1. `array` *(Array)*: The array to recursively flatten. +1. `array` *(Array)*: The array to flatten. #### Returns *(Array)*: Returns the new flattened array. #### Example ```js -_.flattenDeep([1, [2, 3, [4]]]); -// => [1, 2, 3, 4] +_.flattenDeep([1, [2, [3, [4]], 5]]); +// => [1, 2, 3, 4, 5] +``` +* * * + + + + + +### `_.flattenDepth(array, [depth=1])` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5912 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flattendepth "See the npm package") + +Recursively flatten `array` up to `depth` times. + +#### Arguments +1. `array` *(Array)*: The array to flatten. +2. `[depth=1]` *(number)*: The maximum recursion depth. + +#### Returns +*(Array)*: Returns the new flattened array. + +#### Example +```js +var array = [1, [2, [3, [4]], 5]]; + +_.flattenDepth(array, 1); +// => [1, 2, [3, [4]], 5] + +_.flattenDepth(array, 2); +// => [1, 2, 3, [4], 5] ``` * * * @@ -875,7 +899,7 @@ _.flattenDeep([1, [2, 3, [4]]]); ### `_.fromPairs(pairs)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5857 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.frompairs "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5935 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.frompairs "See the npm package") The inverse of `_.toPairs`; this method returns an object composed from key-value `pairs`. @@ -898,7 +922,7 @@ _.fromPairs([['fred', 30], ['barney', 40]]); ### `_.head(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5886 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.head "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5964 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.head "See the npm package") Gets the first element of `array`. @@ -926,7 +950,7 @@ _.head([]); ### `_.indexOf(array, value, [fromIndex=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5912 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L5990 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.indexof "See the npm package") Gets the index at which the first occurrence of `value` is found in `array` using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -957,7 +981,7 @@ _.indexOf([1, 2, 1, 2], 2, 2); ### `_.initial(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5937 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.initial "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6015 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.initial "See the npm package") Gets all but the last element of `array`. @@ -979,7 +1003,7 @@ _.initial([1, 2, 3]); ### `_.intersection([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5956 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersection "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6034 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersection "See the npm package") Creates an array of unique values that are included in all given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -1003,7 +1027,7 @@ _.intersection([2, 1], [4, 2], [1, 2]); ### `_.intersectionBy([arrays], [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L5983 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersectionby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6061 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersectionby "See the npm package") This method is like `_.intersection` except that it accepts `iteratee` which is invoked for each element of each `arrays` to generate the criterion @@ -1032,7 +1056,7 @@ _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); ### `_.intersectionWith([arrays], [comparator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6016 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersectionwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6094 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.intersectionwith "See the npm package") This method is like `_.intersection` except that it accepts `comparator` which is invoked to compare elements of `arrays`. The comparator is invoked @@ -1060,7 +1084,7 @@ _.intersectionWith(objects, others, _.isEqual); ### `_.join(array, [separator=','])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6044 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.join "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6122 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.join "See the npm package") Converts all elements in `array` into a string separated by `separator`. @@ -1083,7 +1107,7 @@ _.join(['a', 'b', 'c'], '~'); ### `_.last(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6061 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.last "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6139 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.last "See the npm package") Gets the last element of `array`. @@ -1105,7 +1129,7 @@ _.last([1, 2, 3]); ### `_.lastIndexOf(array, value, [fromIndex=array.length-1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6086 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lastindexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6164 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lastindexof "See the npm package") This method is like `_.indexOf` except that it iterates over elements of `array` from right to left. @@ -1134,7 +1158,7 @@ _.lastIndexOf([1, 2, 1, 2], 2, 2); ### `_.pull(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6128 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pull "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6206 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pull "See the npm package") Removes all given values from `array` using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -1165,7 +1189,7 @@ console.log(array); ### `_.pullAll(array, values)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6149 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullall "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6227 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullall "See the npm package") This method is like `_.pull` except that it accepts an array of values to remove.
@@ -1194,7 +1218,7 @@ console.log(array); ### `_.pullAllBy(array, values, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6177 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullallby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6255 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullallby "See the npm package") This method is like `_.pullAll` except that it accepts `iteratee` which is invoked for each element of `array` and `values` to generate the criterion @@ -1226,7 +1250,7 @@ console.log(array); ### `_.pullAt(array, [indexes])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6207 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6285 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pullat "See the npm package") Removes elements from `array` corresponding to `indexes` and returns an array of removed elements. @@ -1259,7 +1283,7 @@ console.log(evens); ### `_.remove(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6241 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.remove "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6319 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.remove "See the npm package") Removes all elements from `array` that `predicate` returns truthy for and returns an array of the removed elements. The predicate is invoked with @@ -1295,7 +1319,7 @@ console.log(evens); ### `_.reverse()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6283 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reverse "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6361 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reverse "See the npm package") Reverses `array` so that the first element becomes the last, the second element becomes the second to last, and so on. @@ -1324,7 +1348,7 @@ console.log(array); ### `_.slice(array, [start=0], [end=array.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6301 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.slice "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6379 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.slice "See the npm package") Creates a slice of `array` from `start` up to, but not including, `end`.
@@ -1347,7 +1371,7 @@ to ensure dense arrays are returned. ### `_.sortedIndex(array, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6335 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6413 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindex "See the npm package") Uses a binary search to determine the lowest index at which `value` should be inserted into `array` in order to maintain its sort order. @@ -1374,7 +1398,7 @@ _.sortedIndex([4, 5], 4); ### `_.sortedIndexBy(array, value, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6362 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindexby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6440 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindexby "See the npm package") This method is like `_.sortedIndex` except that it accepts `iteratee` which is invoked for `value` and each element of `array` to compute their @@ -1406,7 +1430,7 @@ _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); ### `_.sortedIndexOf(array, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6381 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6459 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedindexof "See the npm package") This method is like `_.indexOf` except that it performs a binary search on a sorted `array`. @@ -1430,7 +1454,7 @@ _.sortedIndexOf([1, 1, 2, 2], 2); ### `_.sortedLastIndex(array, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6408 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6486 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindex "See the npm package") This method is like `_.sortedIndex` except that it returns the highest index at which `value` should be inserted into `array` in order to @@ -1455,7 +1479,7 @@ _.sortedLastIndex([4, 5], 4); ### `_.sortedLastIndexBy(array, value, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6430 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindexby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6508 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindexby "See the npm package") This method is like `_.sortedLastIndex` except that it accepts `iteratee` which is invoked for `value` and each element of `array` to compute their @@ -1482,7 +1506,7 @@ _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); ### `_.sortedLastIndexOf(array, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6449 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindexof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6527 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortedlastindexof "See the npm package") This method is like `_.lastIndexOf` except that it performs a binary search on a sorted `array`. @@ -1506,7 +1530,7 @@ _.sortedLastIndexOf([1, 1, 2, 2], 2); ### `_.sortedUniq(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6474 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sorteduniq "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6552 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sorteduniq "See the npm package") This method is like `_.uniq` except that it's designed and optimized for sorted arrays. @@ -1529,7 +1553,7 @@ _.sortedUniq([1, 1, 2]); ### `_.sortedUniqBy(array, [iteratee])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6495 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sorteduniqby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6573 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sorteduniqby "See the npm package") This method is like `_.uniqBy` except that it's designed and optimized for sorted arrays. @@ -1553,7 +1577,7 @@ _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); ### `_.tail(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6514 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tail "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6592 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tail "See the npm package") Gets all but the first element of `array`. @@ -1575,7 +1599,7 @@ _.tail([1, 2, 3]); ### `_.take(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6542 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.take "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6620 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.take "See the npm package") Creates a slice of `array` with `n` elements taken from the beginning. @@ -1607,7 +1631,7 @@ _.take([1, 2, 3], 0); ### `_.takeRight(array, [n=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6574 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takeright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6652 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takeright "See the npm package") Creates a slice of `array` with `n` elements taken from the end. @@ -1639,7 +1663,7 @@ _.takeRight([1, 2, 3], 0); ### `_.takeRightWhile(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6618 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6696 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takerightwhile "See the npm package") Creates a slice of `array` with elements taken from the end. Elements are taken until `predicate` returns falsey. The predicate is invoked with three @@ -1682,7 +1706,7 @@ _.takeRightWhile(users, 'active'); ### `_.takeWhile(array, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6658 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takewhile "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6736 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.takewhile "See the npm package") Creates a slice of `array` with elements taken from the beginning. Elements are taken until `predicate` returns falsey. The predicate is invoked with @@ -1725,7 +1749,7 @@ _.takeWhile(users, 'active'); ### `_.union([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6679 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.union "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6757 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.union "See the npm package") Creates an array of unique values, in order, from all given arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -1749,7 +1773,7 @@ _.union([2, 1], [4, 2], [1, 2]); ### `_.unionBy([arrays], [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6703 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unionby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6781 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unionby "See the npm package") This method is like `_.union` except that it accepts `iteratee` which is invoked for each element of each `arrays` to generate the criterion by which @@ -1778,7 +1802,7 @@ _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); ### `_.unionWith([arrays], [comparator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6730 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unionwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6808 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unionwith "See the npm package") This method is like `_.union` except that it accepts `comparator` which is invoked to compare elements of `arrays`. The comparator is invoked @@ -1806,7 +1830,7 @@ _.unionWith(objects, others, _.isEqual); ### `_.uniq(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6754 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniq "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6832 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniq "See the npm package") Creates a duplicate-free version of an array, using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -1831,7 +1855,7 @@ _.uniq([2, 1, 2]); ### `_.uniqBy(array, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6780 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6858 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqby "See the npm package") This method is like `_.uniq` except that it accepts `iteratee` which is invoked for each element in `array` to generate the criterion by which @@ -1860,7 +1884,7 @@ _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); ### `_.uniqWith(array, [comparator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6804 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6882 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqwith "See the npm package") This method is like `_.uniq` except that it accepts `comparator` which is invoked to compare elements of `array`. The comparator is invoked with @@ -1887,7 +1911,7 @@ _.uniqWith(objects, _.isEqual); ### `_.unzip(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6828 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6906 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzip "See the npm package") This method is like `_.zip` except that it accepts an array of grouped elements and creates an array regrouping the elements to their pre-zip @@ -1914,7 +1938,7 @@ _.unzip(zipped); ### `_.unzipWith(array, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzipwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6941 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unzipwith "See the npm package") This method is like `_.unzip` except that it accepts `iteratee` to specify how regrouped values should be combined. The iteratee is invoked with the @@ -1942,7 +1966,7 @@ _.unzipWith(zipped, _.add); ### `_.without(array, [values])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6892 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.without "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6970 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.without "See the npm package") Creates an array excluding all given values using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -1967,7 +1991,7 @@ _.without([1, 2, 1, 3], 1, 2); ### `_.xor([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6912 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xor "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L6990 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xor "See the npm package") Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) of the given arrays. @@ -1990,7 +2014,7 @@ _.xor([2, 1], [4, 2]); ### `_.xorBy([arrays], [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6936 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xorby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7014 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xorby "See the npm package") This method is like `_.xor` except that it accepts `iteratee` which is invoked for each element of each `arrays` to generate the criterion by which @@ -2019,7 +2043,7 @@ _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); ### `_.xorWith([arrays], [comparator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6963 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xorwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7041 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.xorwith "See the npm package") This method is like `_.xor` except that it accepts `comparator` which is invoked to compare elements of `arrays`. The comparator is invoked with @@ -2047,7 +2071,7 @@ _.xorWith(objects, others, _.isEqual); ### `_.zip([arrays])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L6986 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7064 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zip "See the npm package") Creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements @@ -2071,7 +2095,7 @@ _.zip(['fred', 'barney'], [30, 40], [true, false]); ### `_.zipObject([props=[]], [values=[]])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7003 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7081 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobject "See the npm package") This method is like `_.fromPairs` except that it accepts two arrays, one of property names and one of corresponding values. @@ -2095,7 +2119,7 @@ _.zipObject(['a', 'b'], [1, 2]); ### `_.zipObjectDeep([props=[]], [values=[]])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7021 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobjectdeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7099 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipobjectdeep "See the npm package") This method is like `_.zipObject` except that it supports property paths. @@ -2118,7 +2142,7 @@ _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); ### `_.zipWith([arrays], [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7043 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7121 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.zipwith "See the npm package") This method is like `_.zip` except that it accepts `iteratee` to specify how grouped values should be combined. The iteratee is invoked with the @@ -2151,7 +2175,7 @@ _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { ### `_.countBy(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7425 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.countby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7512 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.countby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2180,7 +2204,7 @@ _.countBy(['one', 'two', 'three'], 'length'); ### `_.every(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7463 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.every "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7550 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.every "See the npm package") Checks if `predicate` returns truthy for **all** elements of `collection`. Iteration is stopped once `predicate` returns falsey. The predicate is @@ -2222,7 +2246,7 @@ _.every(users, 'active'); ### `_.filter(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7504 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.filter "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7591 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.filter "See the npm package") Iterates over elements of `collection`, returning an array of all elements `predicate` returns truthy for. The predicate is invoked with three arguments:
@@ -2264,7 +2288,7 @@ _.filter(users, 'active'); ### `_.find(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7543 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.find "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7630 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.find "See the npm package") Iterates over elements of `collection`, returning the first element `predicate` returns truthy for. The predicate is invoked with three arguments:
@@ -2307,7 +2331,7 @@ _.find(users, 'active'); ### `_.findLast(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7569 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlast "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7656 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlast "See the npm package") This method is like `_.find` except that it iterates over elements of `collection` from right to left. @@ -2333,7 +2357,7 @@ _.findLast([1, 2, 3, 4], function(n) { ### `_.flatMap(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7598 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatmap "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7685 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flatmap "See the npm package") Creates an array of flattened values by running each element in `collection` through `iteratee` and concating its result to the other mapped values. @@ -2362,7 +2386,7 @@ _.flatMap([1, 2], duplicate); ### `_.forEach(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7630 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreach "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7717 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreach "See the npm package") Iterates over elements of `collection` invoking `iteratee` for each element. The iteratee is invoked with three arguments: (value, index|key, collection). @@ -2402,7 +2426,7 @@ _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { ### `_.forEachRight(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7654 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreachright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7741 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.foreachright "See the npm package") This method is like `_.forEach` except that it iterates over elements of `collection` from right to left. @@ -2431,7 +2455,7 @@ _.forEachRight([1, 2], function(value) { ### `_.groupBy(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7681 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.groupby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7768 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.groupby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2461,7 +2485,7 @@ _.groupBy(['one', 'two', 'three'], 'length'); ### `_.includes(collection, value, [fromIndex=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7717 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.includes "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7804 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.includes "See the npm package") Checks if `value` is in `collection`. If `collection` is a string it's checked for a substring of `value`, otherwise [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) @@ -2497,7 +2521,7 @@ _.includes('pebbles', 'eb'); ### `_.invokeMap(collection, path, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7752 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invokemap "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7839 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invokemap "See the npm package") Invokes the method at `path` of each element in `collection`, returning an array of the results of each invoked method. Any additional arguments @@ -2527,7 +2551,7 @@ _.invokeMap([123, 456], String.prototype.split, ''); ### `_.keyBy(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7792 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keyby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7879 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keyby "See the npm package") Creates an object composed of keys generated from the results of running each element of `collection` through `iteratee`. The corresponding value @@ -2563,7 +2587,7 @@ _.keyBy(array, 'dir'); ### `_.map(collection, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7837 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.map "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7924 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.map "See the npm package") Creates an array of values by running each element in `collection` through `iteratee`. The iteratee is invoked with three arguments:
@@ -2615,7 +2639,7 @@ _.map(users, 'user'); ### `_.orderBy(collection, [iteratees=[_.identity]], [orders])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7869 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.orderby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7956 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.orderby "See the npm package") This method is like `_.sortBy` except that it allows specifying the sort orders of the iteratees to sort by. If `orders` is unspecified, all values @@ -2650,7 +2674,7 @@ _.orderBy(users, ['user', 'age'], ['asc', 'desc']); ### `_.partition(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7918 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partition "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8005 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partition "See the npm package") Creates an array of elements split into two groups, the first of which contains elements `predicate` returns truthy for, the second of which @@ -2694,7 +2718,7 @@ _.partition(users, 'active'); ### `_.reduce(collection, [iteratee=_.identity], [accumulator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7957 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduce "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8044 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduce "See the npm package") Reduces `collection` to a value which is the accumulated result of running each element in `collection` through `iteratee`, where each successive @@ -2740,7 +2764,7 @@ _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { ### `_.reduceRight(collection, [iteratee=_.identity], [accumulator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7984 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduceright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8071 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reduceright "See the npm package") This method is like `_.reduce` except that it iterates over elements of `collection` from right to left. @@ -2769,7 +2793,7 @@ _.reduceRight(array, function(flattened, other) { ### `_.reject(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8023 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8110 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.reject "See the npm package") The opposite of `_.filter`; this method returns the elements of `collection` that `predicate` does **not** return truthy for. @@ -2810,7 +2834,7 @@ _.reject(users, 'active'); ### `_.sample(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8044 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sample "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8131 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sample "See the npm package") Gets a random element from `collection`. @@ -2832,7 +2856,7 @@ _.sample([1, 2, 3, 4]); ### `_.sampleSize(collection, [n=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8069 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.samplesize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8156 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.samplesize "See the npm package") Gets `n` random elements at unique keys from `collection` up to the size of `collection`. @@ -2859,7 +2883,7 @@ _.sampleSize([1, 2, 3], 4); ### `_.shuffle(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8101 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.shuffle "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8188 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.shuffle "See the npm package") Creates an array of shuffled values, using a version of the [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). @@ -2882,7 +2906,7 @@ _.shuffle([1, 2, 3, 4]); ### `_.size(collection)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8125 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.size "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8212 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.size "See the npm package") Gets the size of `collection` by returning its length for array-like values or the number of own enumerable properties for objects. @@ -2911,7 +2935,7 @@ _.size('pebbles'); ### `_.some(collection, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8170 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.some "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8257 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.some "See the npm package") Checks if `predicate` returns truthy for **any** element of `collection`. Iteration is stopped once `predicate` returns truthy. The predicate is @@ -2953,7 +2977,7 @@ _.some(users, 'active'); ### `_.sortBy(collection, [iteratees=[_.identity]])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8211 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8298 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sortby "See the npm package") Creates an array of elements, sorted in ascending order by the results of running each element in a collection through each iteratee. This method @@ -3000,9 +3024,9 @@ _.sortBy(users, 'user', function(o) { ### `_.now()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8242 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.now "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8329 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.now "See the npm package") -Gets the timestamp of the number of milliseconds that have elapsed since +({Function}): Gets the timestamp of the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC). #### Returns @@ -3028,7 +3052,7 @@ _.defer(function(stamp) { ### `_.after(n, func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8269 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.after "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8356 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.after "See the npm package") The opposite of `_.before`; this method creates a function that invokes `func` once it's called `n` or more times. @@ -3060,7 +3084,7 @@ _.forEach(saves, function(type) { ### `_.ary(func, [n=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8297 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ary "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8384 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ary "See the npm package") Creates a function that accepts up to `n` arguments, ignoring any additional arguments. @@ -3084,7 +3108,7 @@ _.map(['6', '8', '10'], _.ary(parseInt, 1)); ### `_.before(n, func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8319 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.before "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8406 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.before "See the npm package") Creates a function that invokes `func`, with the `this` binding and arguments of the created function, while it's called less than `n` times. Subsequent @@ -3109,7 +3133,7 @@ jQuery(element).on('click', _.before(5, addContactToList)); ### `_.bind(func, thisArg, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8371 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bind "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8458 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bind "See the npm package") Creates a function that invokes `func` with the `this` binding of `thisArg` and prepends any additional `_.bind` arguments to those provided to the @@ -3155,7 +3179,7 @@ bound('hi'); ### `_.bindKey(object, key, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8426 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8513 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindkey "See the npm package") Creates a function that invokes the method at `object[key]` and prepends any additional `_.bindKey` arguments to those provided to the bound function. @@ -3210,7 +3234,7 @@ bound('hi'); ### `_.curry(func, [arity=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8477 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curry "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8564 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curry "See the npm package") Creates a function that accepts arguments of `func` and either invokes `func` returning its result, if at least `arity` number of arguments have @@ -3260,7 +3284,7 @@ curried(1)(_, 3)(2); ### `_.curryRight(func, [arity=func.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8521 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curryright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8608 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.curryright "See the npm package") This method is like `_.curry` except that arguments are applied to `func` in the manner of `_.partialRight` instead of `_.partial`. @@ -3307,7 +3331,7 @@ curried(3)(1, _)(2); ### `_.debounce(func, [wait=0], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8577 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.debounce "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8664 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.debounce "See the npm package") Creates a debounced function that delays invoking `func` until after `wait` milliseconds have elapsed since the last time the debounced function was @@ -3364,7 +3388,7 @@ jQuery(window).on('popstate', debounced.cancel); ### `_.defer(func, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8709 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defer "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8798 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defer "See the npm package") Defers invoking the `func` until the current call stack has cleared. Any additional arguments are provided to `func` when it's invoked. @@ -3390,7 +3414,7 @@ _.defer(function(text) { ### `_.delay(func, wait, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8731 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.delay "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8820 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.delay "See the npm package") Invokes `func` after `wait` milliseconds. Any additional arguments are provided to `func` when it's invoked. @@ -3417,7 +3441,7 @@ _.delay(function(text) { ### `_.flip(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8752 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flip "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8841 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flip "See the npm package") Creates a function that invokes `func` with arguments reversed. @@ -3443,7 +3467,7 @@ flipped('a', 'b', 'c', 'd'); ### `_.memoize(func, [resolver])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8798 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.memoize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8887 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.memoize "See the npm package") Creates a function that memoizes the result of `func`. If `resolver` is provided it determines the cache key for storing the result based on the @@ -3495,7 +3519,7 @@ _.memoize.Cache = WeakMap; ### `_.negate(predicate)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8837 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.negate "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8926 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.negate "See the npm package") Creates a function that negates the result of the predicate `func`. The `func` predicate is invoked with the `this` binding and arguments of the @@ -3523,7 +3547,7 @@ _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); ### `_.once(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.once "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8952 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.once "See the npm package") Creates a function that is restricted to invoking `func` once. Repeat calls to the function return the value of the first invocation. The `func` is @@ -3549,7 +3573,7 @@ initialize(); ### `_.overArgs(func, [transforms])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8898 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.overargs "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L8987 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.overargs "See the npm package") Creates a function that invokes `func` with arguments transformed by corresponding `transforms`. @@ -3588,7 +3612,7 @@ func(10, 5); ### `_.partial(func, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8945 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partial "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9034 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partial "See the npm package") Creates a function that invokes `func` with `partial` arguments prepended to those provided to the new function. This method is like `_.bind` except @@ -3631,7 +3655,7 @@ greetFred('hi'); ### `_.partialRight(func, [partials])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L8983 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partialright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9072 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.partialright "See the npm package") This method is like `_.partial` except that partially applied arguments are appended to those provided to the new function. @@ -3673,7 +3697,7 @@ sayHelloTo('fred'); ### `_.rearg(func, indexes)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9012 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rearg "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9101 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rearg "See the npm package") Creates a function that invokes `func` with arguments arranged according to the specified indexes where the argument value at the first index is @@ -3703,7 +3727,7 @@ rearged('b', 'c', 'a') ### `_.rest(func, [start=func.length-1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9038 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rest "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9127 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rest "See the npm package") Creates a function that invokes `func` with the `this` binding of the created function and arguments from `start` and beyond provided as an array. @@ -3735,7 +3759,7 @@ say('hello', 'fred', 'barney', 'pebbles'); ### `_.spread(func, [start=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9098 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.spread "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9187 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.spread "See the npm package") Creates a function that invokes `func` with the `this` binding of the created function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). @@ -3776,7 +3800,7 @@ numbers.then(_.spread(function(x, y) { ### `_.throttle(func, [wait=0], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9154 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.throttle "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9243 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.throttle "See the npm package") Creates a throttled function that only invokes `func` at most once per every `wait` milliseconds. The throttled function comes with a `cancel` @@ -3825,7 +3849,7 @@ jQuery(window).on('popstate', throttled.cancel); ### `_.unary(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9182 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unary "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9275 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unary "See the npm package") Creates a function that accepts up to one argument, ignoring any additional arguments. @@ -3847,8 +3871,8 @@ _.map(['6', '8', '10'], _.unary(parseInt)); -### `_.wrap(value, wrapper)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9207 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.wrap "See the npm package") +### `_.wrap(value, [wrapper=identity])` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9300 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.wrap "See the npm package") Creates a function that provides `value` to the wrapper function as its first argument. Any additional arguments provided to the function are @@ -3857,7 +3881,7 @@ with the `this` binding of the created function. #### Arguments 1. `value` *(*)*: The value to wrap. -2. `wrapper` *(Function)*: The wrapper function. +2. `[wrapper=identity]` *(Function)*: The wrapper function. #### Returns *(Function)*: Returns the new function. @@ -3883,8 +3907,49 @@ p('fred, barney, & pebbles'); +### `_.castArray(value)` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9339 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.castarray "See the npm package") + +Casts `value` as an array if it's not one. + +#### Arguments +1. `value` *(*)*: The value to inspect. + +#### Returns +*(Array)*: Returns the cast array. + +#### Example +```js +_.castArray(1); +// => [1] + +_.castArray({ 'a': 1 }); +// => [{ 'a': 1 }] + +_.castArray('abc'); +// => ['abc'] + +_.castArray(null); +// => [null] + +_.castArray(undefined); +// => [undefined] + +_.castArray(); +// => [] + +var array = [1, 2, 3]; +console.log(_.castArray(array) === array); +// => true +``` +* * * + + + + + ### `_.clone(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9238 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clone "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9371 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clone "See the npm package") Creates a shallow clone of `value`.
@@ -3918,7 +3983,7 @@ console.log(shallow[0] === objects[0]); ### `_.cloneDeep(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9291 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9424 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeep "See the npm package") This method is like `_.clone` except that it recursively clones `value`. @@ -3943,7 +4008,7 @@ console.log(deep[0] === objects[0]); ### `_.cloneDeepWith(value, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9321 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeepwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9454 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonedeepwith "See the npm package") This method is like `_.cloneWith` except that it recursively clones `value`. @@ -3978,7 +4043,7 @@ console.log(el.childNodes.length); ### `_.cloneWith(value, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9271 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonewith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9404 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clonewith "See the npm package") This method is like `_.clone` except that it accepts `customizer` which is invoked to produce the cloned value. If `customizer` returns `undefined` @@ -4016,7 +4081,7 @@ console.log(el.childNodes.length); ### `_.eq(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9355 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.eq "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9488 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.eq "See the npm package") Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) comparison between two values to determine if they are equivalent. @@ -4055,7 +4120,7 @@ _.eq(NaN, NaN); ### `_.gt(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9379 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9512 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gt "See the npm package") Checks if `value` is greater than `other`. @@ -4084,7 +4149,7 @@ _.gt(1, 3); ### `_.gte(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9403 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gte "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9536 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.gte "See the npm package") Checks if `value` is greater than or equal to `other`. @@ -4113,7 +4178,7 @@ _.gte(1, 3); ### `_.isArguments(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9423 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarguments "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9556 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarguments "See the npm package") Checks if `value` is likely an `arguments` object. @@ -4138,9 +4203,9 @@ _.isArguments([1, 2, 3]); ### `_.isArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9452 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9585 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarray "See the npm package") -Checks if `value` is classified as an `Array` object. +({Function}): Checks if `value` is classified as an `Array` object. #### Arguments 1. `value` *(*)*: The value to check. @@ -4169,7 +4234,7 @@ _.isArray(_.noop); ### `_.isArrayBuffer(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9471 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarraybuffer "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9603 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarraybuffer "See the npm package") Checks if `value` is classified as an `ArrayBuffer` object. @@ -4194,7 +4259,7 @@ _.isArrayBuffer(new Array(2)); ### `_.isArrayLike(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9500 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarraylike "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9631 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarraylike "See the npm package") Checks if `value` is array-like. A value is considered array-like if it's not a function and has a `value.length` that's an integer greater than or @@ -4227,7 +4292,7 @@ _.isArrayLike(_.noop); ### `_.isArrayLikeObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9529 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarraylikeobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9659 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isarraylikeobject "See the npm package") This method is like `_.isArrayLike` except that it also checks if `value` is an object. @@ -4259,7 +4324,7 @@ _.isArrayLikeObject(_.noop); ### `_.isBoolean(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9549 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isboolean "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9679 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isboolean "See the npm package") Checks if `value` is classified as a boolean primitive or object. @@ -4284,7 +4349,7 @@ _.isBoolean(null); ### `_.isBuffer(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9570 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isbuffer "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9700 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isbuffer "See the npm package") Checks if `value` is a buffer. @@ -4309,7 +4374,7 @@ _.isBuffer(new Uint8Array(2)); ### `_.isDate(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9590 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isdate "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9720 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isdate "See the npm package") Checks if `value` is classified as a `Date` object. @@ -4334,7 +4399,7 @@ _.isDate('Mon April 23 2012'); ### `_.isElement(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9610 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iselement "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9740 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iselement "See the npm package") Checks if `value` is likely a DOM element. @@ -4359,7 +4424,7 @@ _.isElement(''); ### `_.isEmpty(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9641 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isempty "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9771 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isempty "See the npm package") Checks if `value` is empty. A value is considered empty unless it's an `arguments` object, array, string, or jQuery-like collection with a length @@ -4395,7 +4460,7 @@ _.isEmpty({ 'a': 1 }); ### `_.isEqual(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9681 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequal "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9812 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequal "See the npm package") Performs a deep comparison between two values to determine if they are equivalent. @@ -4432,12 +4497,12 @@ object === other; ### `_.isEqualWith(value, other, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9716 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequalwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9847 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isequalwith "See the npm package") -This method is like `_.isEqual` except that it accepts `customizer` which is -invoked to compare values. If `customizer` returns `undefined` comparisons are -handled by the method instead. The `customizer` is invoked with up to six arguments:
-(objValue, othValue [, index|key, object, other, stack]). +This method is like `_.isEqual` except that it accepts `customizer` which +is invoked to compare values. If `customizer` returns `undefined` comparisons +are handled by the method instead. The `customizer` is invoked with up to +six arguments: (objValue, othValue [, index|key, object, other, stack]). #### Arguments 1. `value` *(*)*: The value to compare. @@ -4472,7 +4537,7 @@ _.isEqualWith(array, other, customizer); ### `_.isError(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9739 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iserror "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9870 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iserror "See the npm package") Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, `SyntaxError`, `TypeError`, or `URIError` object. @@ -4498,7 +4563,7 @@ _.isError(Error); ### `_.isFinite(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9768 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfinite "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9903 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfinite "See the npm package") Checks if `value` is a finite primitive number.
@@ -4532,7 +4597,7 @@ _.isFinite(Infinity); ### `_.isFunction(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9788 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfunction "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9923 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isfunction "See the npm package") Checks if `value` is classified as a `Function` object. @@ -4557,7 +4622,7 @@ _.isFunction(/abc/); ### `_.isInteger(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9820 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isinteger "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9955 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isinteger "See the npm package") Checks if `value` is an integer.
@@ -4591,7 +4656,7 @@ _.isInteger('3'); ### `_.isLength(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9848 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.islength "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L9983 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.islength "See the npm package") Checks if `value` is a valid array-like length.
@@ -4625,7 +4690,7 @@ _.isLength('3'); ### `_.isMap(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9923 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismap "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10059 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismap "See the npm package") Checks if `value` is classified as a `Map` object. @@ -4650,10 +4715,11 @@ _.isMap(new WeakMap); ### `_.isMatch(object, source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9949 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatch "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10086 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatch "See the npm package") -Performs a deep comparison between `object` and `source` to determine if -`object` contains equivalent property values. +Performs a partial deep comparison between `object` and `source` to +determine if `object` contains equivalent property values. This method is +equivalent to a `_.matches` function when `source` is partially applied.

**Note:** This method supports comparing the same values as `_.isEqual`. @@ -4682,7 +4748,7 @@ _.isMatch(object, { 'age': 36 }); ### `_.isMatchWith(object, source, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9984 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatchwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10121 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ismatchwith "See the npm package") This method is like `_.isMatch` except that it accepts `customizer` which is invoked to compare values. If `customizer` returns `undefined` comparisons @@ -4722,7 +4788,7 @@ _.isMatchWith(object, source, customizer); ### `_.isNaN(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10014 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnan "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10151 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnan "See the npm package") Checks if `value` is `NaN`.
@@ -4757,7 +4823,7 @@ _.isNaN(undefined); ### `_.isNative(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10036 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnative "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10173 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnative "See the npm package") Checks if `value` is a native function. @@ -4782,7 +4848,7 @@ _.isNative(_); ### `_.isNil(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10086 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnil "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10223 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnil "See the npm package") Checks if `value` is `null` or `undefined`. @@ -4810,7 +4876,7 @@ _.isNil(NaN); ### `_.isNull(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10063 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnull "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10200 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnull "See the npm package") Checks if `value` is `null`. @@ -4835,7 +4901,7 @@ _.isNull(void 0); ### `_.isNumber(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10115 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnumber "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10252 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isnumber "See the npm package") Checks if `value` is classified as a `Number` primitive or object.
@@ -4870,7 +4936,7 @@ _.isNumber('3'); ### `_.isObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9875 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10011 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobject "See the npm package") Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) @@ -4902,7 +4968,7 @@ _.isObject(null); ### `_.isObjectLike(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L9903 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobjectlike "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10039 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isobjectlike "See the npm package") Checks if `value` is object-like. A value is object-like if it's not `null` and has a `typeof` result of "object". @@ -4934,7 +5000,7 @@ _.isObjectLike(null); ### `_.isPlainObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10147 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isplainobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10284 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isplainobject "See the npm package") Checks if `value` is a plain object, that is, an object created by the `Object` constructor or one with a `[[Prototype]]` of `null`. @@ -4970,7 +5036,7 @@ _.isPlainObject(Object.create(null)); ### `_.isRegExp(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10179 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isregexp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10317 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isregexp "See the npm package") Checks if `value` is classified as a `RegExp` object. @@ -4995,7 +5061,7 @@ _.isRegExp('/abc/'); ### `_.isSafeInteger(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10208 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.issafeinteger "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10346 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.issafeinteger "See the npm package") Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 double precision number which isn't the result of a rounded unsafe integer. @@ -5030,7 +5096,7 @@ _.isSafeInteger('3'); ### `_.isSet(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10228 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isset "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10366 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isset "See the npm package") Checks if `value` is classified as a `Set` object. @@ -5055,7 +5121,7 @@ _.isSet(new WeakSet); ### `_.isString(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10248 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isstring "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10386 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isstring "See the npm package") Checks if `value` is classified as a `String` primitive or object. @@ -5080,7 +5146,7 @@ _.isString(1); ### `_.isSymbol(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10269 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.issymbol "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10407 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.issymbol "See the npm package") Checks if `value` is classified as a `Symbol` primitive or object. @@ -5105,7 +5171,7 @@ _.isSymbol('abc'); ### `_.isTypedArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10290 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.istypedarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10428 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.istypedarray "See the npm package") Checks if `value` is classified as a typed array. @@ -5130,7 +5196,7 @@ _.isTypedArray([]); ### `_.isUndefined(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10310 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isundefined "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10449 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isundefined "See the npm package") Checks if `value` is `undefined`. @@ -5155,7 +5221,7 @@ _.isUndefined(null); ### `_.isWeakMap(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10330 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isweakmap "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10469 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isweakmap "See the npm package") Checks if `value` is classified as a `WeakMap` object. @@ -5180,7 +5246,7 @@ _.isWeakMap(new Map); ### `_.isWeakSet(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10350 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isweakset "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10489 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.isweakset "See the npm package") Checks if `value` is classified as a `WeakSet` object. @@ -5205,7 +5271,7 @@ _.isWeakSet(new Set); ### `_.lt(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10374 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10513 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lt "See the npm package") Checks if `value` is less than `other`. @@ -5234,7 +5300,7 @@ _.lt(3, 1); ### `_.lte(value, other)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10398 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lte "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10537 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lte "See the npm package") Checks if `value` is less than or equal to `other`. @@ -5263,7 +5329,7 @@ _.lte(3, 1); ### `_.toArray(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10424 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toarray "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10563 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toarray "See the npm package") Converts `value` to an array. @@ -5294,7 +5360,7 @@ _.toArray(null); ### `_.toInteger(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10464 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tointeger "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10603 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tointeger "See the npm package") Converts `value` to an integer.
@@ -5328,7 +5394,7 @@ _.toInteger('3'); ### `_.toLength(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10502 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tolength "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10641 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tolength "See the npm package") Converts `value` to an integer suitable for use as the length of an array-like object. @@ -5363,7 +5429,7 @@ _.toLength('3'); ### `_.toNumber(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10528 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tonumber "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10667 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tonumber "See the npm package") Converts `value` to a number. @@ -5394,7 +5460,7 @@ _.toNumber('3'); ### `_.toPlainObject(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10566 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toplainobject "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10705 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toplainobject "See the npm package") Converts `value` to a plain object flattening inherited enumerable properties of `value` to own properties of the plain object. @@ -5426,7 +5492,7 @@ _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); ### `_.toSafeInteger(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10593 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tosafeinteger "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10732 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tosafeinteger "See the npm package") Converts `value` to a safe integer. A safe integer can be compared and represented correctly. @@ -5458,7 +5524,7 @@ _.toSafeInteger('3'); ### `_.toString(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10617 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tostring "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10756 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tostring "See the npm package") Converts `value` to a string if it's not one. An empty string is returned for `null` and `undefined` values. The sign of `-0` is preserved. @@ -5493,7 +5559,7 @@ _.toString([1, 2, 3]); ### `_.add(augend, addend)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13863 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.add "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14017 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.add "See the npm package") Adds two numbers. @@ -5516,7 +5582,7 @@ _.add(6, 4); ### `_.ceil(number, [precision=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13897 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ceil "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14051 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ceil "See the npm package") Computes `number` rounded up to `precision`. @@ -5545,7 +5611,7 @@ _.ceil(6040, -2); ### `_.floor(number, [precision=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13919 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.floor "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14073 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.floor "See the npm package") Computes `number` rounded down to `precision`. @@ -5574,7 +5640,7 @@ _.floor(4060, -2); ### `_.max(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13938 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.max "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14092 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.max "See the npm package") Computes the maximum value of `array`. If `array` is empty or falsey `undefined` is returned. @@ -5600,7 +5666,7 @@ _.max([]); ### `_.maxBy(array, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13966 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.maxby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14120 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.maxby "See the npm package") This method is like `_.max` except that it accepts `iteratee` which is invoked for each element in `array` to generate the criterion by which @@ -5631,7 +5697,7 @@ _.maxBy(objects, 'n'); ### `_.mean(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13985 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mean "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14139 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mean "See the npm package") Computes the mean of the values in `array`. @@ -5653,7 +5719,7 @@ _.mean([4, 2, 8, 6]); ### `_.min(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14006 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.min "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14160 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.min "See the npm package") Computes the minimum value of `array`. If `array` is empty or falsey `undefined` is returned. @@ -5679,7 +5745,7 @@ _.min([]); ### `_.minBy(array, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14034 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.minby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14188 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.minby "See the npm package") This method is like `_.min` except that it accepts `iteratee` which is invoked for each element in `array` to generate the criterion by which @@ -5710,7 +5776,7 @@ _.minBy(objects, 'n'); ### `_.round(number, [precision=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14060 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.round "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14214 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.round "See the npm package") Computes `number` rounded to `precision`. @@ -5739,7 +5805,7 @@ _.round(4060, -2); ### `_.subtract(minuend, subtrahend)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14076 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.subtract "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14230 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.subtract "See the npm package") Subtract two numbers. @@ -5762,7 +5828,7 @@ _.subtract(6, 4); ### `_.sum(array)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14103 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sum "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14257 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sum "See the npm package") Computes the sum of the values in `array`. @@ -5784,7 +5850,7 @@ _.sum([4, 2, 8, 6]); ### `_.sumBy(array, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14131 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sumby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14285 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.sumby "See the npm package") This method is like `_.sum` except that it accepts `iteratee` which is invoked for each element in `array` to generate the value to be summed. @@ -5821,7 +5887,7 @@ _.sumBy(objects, 'n'); ### `_.clamp(number, [lower], upper)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11892 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clamp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12037 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.clamp "See the npm package") Clamps `number` within the inclusive `lower` and `upper` bounds. @@ -5848,7 +5914,7 @@ _.clamp(10, -5, 5); ### `_.inRange(number, [start=0], end)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11944 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.inrange "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12089 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.inrange "See the npm package") Checks if `n` is between `start` and up to but not including, `end`. If `end` is not specified it's set to `start` with `start` then set to `0`. @@ -5893,7 +5959,7 @@ _.inRange(-3, -2, -6); ### `_.random([lower=0], [upper=1], [floating])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11986 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.random "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12131 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.random "See the npm package") Produces a random number between the inclusive `lower` and `upper` bounds. If only one argument is provided a number between `0` and the given number @@ -5939,7 +6005,7 @@ _.random(1.2, 5.2); ### `_.assign(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10664 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assign "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10803 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assign "See the npm package") Assigns own enumerable properties of source objects to the destination object. Source objects are applied from left to right. Subsequent sources @@ -5979,7 +6045,7 @@ _.assign({ 'a': 1 }, new Foo, new Bar); ### `_.assignIn(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10697 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assignin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10836 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assignin "See the npm package") This method is like `_.assign` except that it iterates over own and inherited source properties. @@ -6020,7 +6086,7 @@ _.assignIn({ 'a': 1 }, new Foo, new Bar); ### `_.assignInWith(object, sources, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10728 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assigninwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10867 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assigninwith "See the npm package") This method is like `_.assignIn` except that it accepts `customizer` which is invoked to produce the assigned values. If `customizer` returns `undefined` @@ -6059,7 +6125,7 @@ defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); ### `_.assignWith(object, sources, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10758 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assignwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10897 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.assignwith "See the npm package") This method is like `_.assign` except that it accepts `customizer` which is invoked to produce the assigned values. If `customizer` returns `undefined` @@ -6095,7 +6161,7 @@ defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); ### `_.at(object, [paths])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10782 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.at "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10921 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.at "See the npm package") Creates an array of values corresponding to `paths` of `object`. @@ -6123,7 +6189,7 @@ _.at(['a', 'b', 'c'], 0, 2); ### `_.create(prototype, [properties])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10818 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.create "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10957 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.create "See the npm package") Creates an object that inherits from the `prototype` object. If a `properties` object is given its own enumerable properties are assigned to the created object. @@ -6164,7 +6230,7 @@ circle instanceof Shape; ### `_.defaults(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10842 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaults "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L10981 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaults "See the npm package") Assigns own and inherited enumerable properties of source objects to the destination object for all destination properties that resolve to `undefined`. @@ -6193,7 +6259,7 @@ _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); ### `_.defaultsDeep(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10865 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaultsdeep "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11004 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.defaultsdeep "See the npm package") This method is like `_.defaults` except that it recursively assigns default properties. @@ -6220,7 +6286,7 @@ _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'ag ### `_.findKey(object, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10903 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11042 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findkey "See the npm package") This method is like `_.find` except that it returns the key of the first element `predicate` returns truthy for instead of the element itself. @@ -6262,7 +6328,7 @@ _.findKey(users, 'active'); ### `_.findLastKey(object, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10940 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastkey "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11079 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.findlastkey "See the npm package") This method is like `_.findKey` except that it iterates over elements of a collection in the opposite order. @@ -6304,7 +6370,7 @@ _.findLastKey(users, 'active'); ### `_.forIn(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10970 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11109 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forin "See the npm package") Iterates over own and inherited enumerable properties of an object invoking `iteratee` for each property. The iteratee is invoked with three arguments:
@@ -6339,7 +6405,7 @@ _.forIn(new Foo, function(value, key) { ### `_.forInRight(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L10998 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forinright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11139 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forinright "See the npm package") This method is like `_.forIn` except that it iterates over properties of `object` in the opposite order. @@ -6372,7 +6438,7 @@ _.forInRight(new Foo, function(value, key) { ### `_.forOwn(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11028 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forown "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11171 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forown "See the npm package") Iterates over own enumerable properties of an object invoking `iteratee` for each property. The iteratee is invoked with three arguments:
@@ -6407,7 +6473,7 @@ _.forOwn(new Foo, function(value, key) { ### `_.forOwnRight(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11056 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forownright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11199 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.forownright "See the npm package") This method is like `_.forOwn` except that it iterates over properties of `object` in the opposite order. @@ -6440,7 +6506,7 @@ _.forOwnRight(new Foo, function(value, key) { ### `_.functions(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11081 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functions "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11224 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functions "See the npm package") Creates an array of function property names from own enumerable properties of `object`. @@ -6470,7 +6536,7 @@ _.functions(new Foo); ### `_.functionsIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11106 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functionsin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11249 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.functionsin "See the npm package") Creates an array of function property names from own and inherited enumerable properties of `object`. @@ -6500,7 +6566,7 @@ _.functionsIn(new Foo); ### `_.get(object, path, [defaultValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11134 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.get "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11277 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.get "See the npm package") Gets the value at `path` of `object`. If the resolved value is `undefined` the `defaultValue` is used in its place. @@ -6533,7 +6599,7 @@ _.get(object, 'a.b.c', 'default'); ### `_.has(object, path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11165 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.has "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11308 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.has "See the npm package") Checks if `path` is a direct property of `object`. @@ -6568,7 +6634,7 @@ _.has(other, 'a'); ### `_.hasIn(object, path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11194 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.hasin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11337 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.hasin "See the npm package") Checks if `path` is a direct or inherited property of `object`. @@ -6602,7 +6668,7 @@ _.hasIn(object, 'b'); ### `_.invert(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11215 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invert "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11358 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invert "See the npm package") Creates an object composed of the inverted keys and values of `object`. If `object` contains duplicate values, subsequent values overwrite property @@ -6628,7 +6694,7 @@ _.invert(object); ### `_.invertBy(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11244 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invertby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11387 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invertby "See the npm package") This method is like `_.invert` except that the inverted object is generated from the results of running each element of `object` through `iteratee`. @@ -6662,7 +6728,7 @@ _.invertBy(object, function(value) { ### `_.invoke(object, path, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11269 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invoke "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11412 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.invoke "See the npm package") Invokes the method at `path` of `object`. @@ -6688,7 +6754,7 @@ _.invoke(object, 'a[0].b.c.slice', 1, 3); ### `_.keys(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11298 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keys "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11441 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keys "See the npm package") Creates an array of the own enumerable property names of `object`.
@@ -6725,7 +6791,7 @@ _.keys('hi'); ### `_.keysIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11340 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keysin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11483 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.keysin "See the npm package") Creates an array of the own and inherited enumerable property names of `object`.
@@ -6757,7 +6823,7 @@ _.keysIn(new Foo); ### `_.mapKeys(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11378 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapkeys "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11521 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapkeys "See the npm package") The opposite of `_.mapValues`; this method creates an object with the same values as `object` and keys generated by running each own enumerable @@ -6784,7 +6850,7 @@ _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { ### `_.mapValues(object, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11413 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapvalues "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11556 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mapvalues "See the npm package") Creates an object with the same keys as `object` and values generated by running each own enumerable property of `object` through `iteratee`. The @@ -6818,14 +6884,14 @@ _.mapValues(users, 'age'); ### `_.merge(object, [sources])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11452 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.merge "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11595 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.merge "See the npm package") -Recursively merges own and inherited enumerable properties of source -objects into the destination object, skipping source properties that resolve -to `undefined`. Array and plain object properties are merged recursively. -Other objects and value types are overridden by assignment. Source objects -are applied from left to right. Subsequent sources overwrite property -assignments of previous sources. +Recursively merges own and inherited enumerable properties of source objects +into the destination object. Source properties that resolve to `undefined` +are skipped if a destination value exists. Array and plain object properties +are merged recursively. Other objects and value types are overridden by +assignment. Source objects are applied from left to right. Subsequent +sources overwrite property assignments of previous sources.

**Note:** This method mutates `object`. @@ -6857,7 +6923,7 @@ _.merge(users, ages); ### `_.mergeWith(object, sources, customizer)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11493 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mergewith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11636 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mergewith "See the npm package") This method is like `_.merge` except that it accepts `customizer` which is invoked to produce the merged values of the destination and source @@ -6904,14 +6970,14 @@ _.mergeWith(object, other, customizer); ### `_.omit(object, [props])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11515 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omit "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11658 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omit "See the npm package") The opposite of `_.pick`; this method creates an object composed of the own and inherited enumerable properties of `object` that are not omitted. #### Arguments 1. `object` *(Object)*: The source object. -2. `[props]` *(...(string|string[])*: The property names to omit, specified individually or in arrays.. +2. `[props]` *(...(string|string[])*: The property names to omit, specified individually or in arrays. #### Returns *(Object)*: Returns the new object. @@ -6930,7 +6996,7 @@ _.omit(object, ['a', 'c']); ### `_.omitBy(object, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11541 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omitby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11684 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.omitby "See the npm package") The opposite of `_.pickBy`; this method creates an object composed of the own and inherited enumerable properties of `object` that `predicate` @@ -6957,7 +7023,7 @@ _.omitBy(object, _.isNumber); ### `_.pick(object, [props])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11565 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pick "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11708 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pick "See the npm package") Creates an object composed of the picked `object` properties. @@ -6982,7 +7048,7 @@ _.pick(object, ['a', 'c']); ### `_.pickBy(object, [predicate=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11586 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pickby "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11729 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pickby "See the npm package") Creates an object composed of the `object` properties `predicate` returns truthy for. The predicate is invoked with two arguments: (value, key). @@ -7008,7 +7074,7 @@ _.pickBy(object, _.isNumber); ### `_.result(object, path, [defaultValue])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11618 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.result "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11761 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.result "See the npm package") This method is like `_.get` except that if the resolved value is a function it's invoked with the `this` binding of its parent object and its result @@ -7045,7 +7111,7 @@ _.result(object, 'a[0].b.c3', _.constant('default')); ### `_.set(object, path, value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11659 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.set "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11802 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.set "See the npm package") Sets the value at `path` of `object`. If a portion of `path` doesn't exist it's created. Arrays are created for missing index properties while objects @@ -7082,7 +7148,7 @@ console.log(object.x[0].y.z); ### `_.setWith(object, path, value, [customizer])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11684 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.setwith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11827 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.setwith "See the npm package") This method is like `_.set` except that it accepts `customizer` which is invoked to produce the objects of `path`. If `customizer` returns `undefined` @@ -7113,9 +7179,10 @@ _.setWith({ '0': { 'length': 2 } }, '[0][1][2]', 3, Object); ### `_.toPairs(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11709 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.topairs "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11853 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.topairs "See the npm package") -Creates an array of own enumerable key-value pairs for `object`. +Creates an array of own enumerable key-value pairs for `object` which +can be consumed by `_.fromPairs`. #### Arguments 1. `object` *(Object)*: The object to query. @@ -7142,9 +7209,10 @@ _.toPairs(new Foo); ### `_.toPairsIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11733 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.topairsin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11878 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.topairsin "See the npm package") -Creates an array of own and inherited enumerable key-value pairs for `object`. +Creates an array of own and inherited enumerable key-value pairs for +`object` which can be consumed by `_.fromPairs`. #### Arguments 1. `object` *(Object)*: The object to query. @@ -7171,7 +7239,7 @@ _.toPairsIn(new Foo); ### `_.transform(object, [iteratee=_.identity], [accumulator])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11765 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.transform "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11910 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.transform "See the npm package") An alternative to `_.reduce`; this method transforms `object` to a new `accumulator` object which is the result of running each of its own enumerable @@ -7208,7 +7276,7 @@ _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { ### `_.unset(object, path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11813 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unset "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11958 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unset "See the npm package") Removes the property at `path` of `object`.
@@ -7244,7 +7312,7 @@ console.log(object); ### `_.values(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11842 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.values "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L11987 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.values "See the npm package") Creates an array of the own enumerable property values of `object`.
@@ -7279,7 +7347,7 @@ _.values('hi'); ### `_.valuesIn(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L11868 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.valuesin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12013 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.valuesin "See the npm package") Creates an array of the own and inherited enumerable property values of `object`.
@@ -7317,7 +7385,7 @@ _.valuesIn(new Foo); ### `_(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1469 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1478 "View in source") [Ⓣ][1] Creates a `lodash` object which wraps `value` to enable implicit method chaining. Methods that operate on and return arrays, collections, and @@ -7366,28 +7434,28 @@ The wrapper methods that support shortcut fusion are:


The chainable wrapper methods are:
-`after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, -`at`, `before`, `bind`, `bindAll`, `bindKey`, `chain`, `chunk`, `commit`, -`compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, `curry`, -`debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, +`after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, +`before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, +`commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, +`curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, `dropRightWhile`, -`dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flip`, `flow`, -`flowRight`, `fromPairs`, `functions`, `functionsIn`, `groupBy`, `initial`, -`intersection`, `intersectionBy`, `intersectionWith`, `invert`, `invertBy`, -`invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, `map`, `mapKeys`, -`mapValues`, `matches`, `matchesProperty`, `memoize`, `merge`, `mergeWith`, -`method`, `methodOf`, `mixin`, `negate`, `nthArg`, `omit`, `omitBy`, `once`, -`orderBy`, `over`, `overArgs`, `overEvery`, `overSome`, `partial`, -`partialRight`, `partition`, `pick`, `pickBy`, `plant`, `property`, -`propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, `range`, -`rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, `sampleSize`, -`set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`, `spread`, -`tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, `throttle`, -`thru`, `toArray`, `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, -`transform`, `unary`, `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, -`uniqWith`, `unset`, `unshift`, `unzip`, `unzipWith`, `values`, `valuesIn`, -`without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, `zipObject`, -`zipObjectDeep`, and `zipWith` +`dropWhile`, `fill`, `filter`, `flatten`, `flattenDeep`, `flattenDepth`, +`flip`, `flow`, `flowRight`, `fromPairs`, `functions`, `functionsIn`, +`groupBy`, `initial`, `intersection`, `intersectionBy`, `intersectionWith`, +`invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, `keys`, `keysIn`, +`map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, `memoize`, +`merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, `nthArg`, +`omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, `overEvery`, +`overSome`, `partial`, `partialRight`, `partition`, `pick`, `pickBy`, `plant`, +`property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, `pullAt`, `push`, +`range`, `rangeRight`, `rearg`, `reject`, `remove`, `rest`, `reverse`, +`sampleSize`, `set`, `setWith`, `shuffle`, `slice`, `sort`, `sortBy`, +`splice`, `spread`, `tail`, `take`, `takeRight`, `takeRightWhile`, +`takeWhile`, `tap`, `throttle`, `thru`, `toArray`, `toPairs`, `toPairsIn`, +`toPath`, `toPlainObject`, `transform`, `unary`, `union`, `unionBy`, +`unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, `unshift`, `unzip`, +`unzipWith`, `values`, `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, +`xorWith`, `zip`, `zipObject`, `zipObjectDeep`, and `zipWith`

The wrapper methods that are **not** chainable by default are:
@@ -7447,7 +7515,7 @@ _.isArray(squares.value()); ### `_.chain(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7080 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7158 "View in source") [Ⓣ][1] Creates a `lodash` object that wraps `value` with explicit method chaining enabled. The result of such method chaining must be unwrapped with `_#value`. @@ -7483,7 +7551,7 @@ var youngest = _ ### `_.tap(value, interceptor)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7108 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7186 "View in source") [Ⓣ][1] This method invokes `interceptor` and returns `value`. The interceptor is invoked with one argument; (value). The purpose of this method is to @@ -7514,7 +7582,7 @@ _([1, 2, 3]) ### `_.thru(value, interceptor)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7135 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7213 "View in source") [Ⓣ][1] This method is like `_.tap` except that it returns the result of `interceptor`. The purpose of this method is to "pass thru" values replacing intermediate @@ -7545,7 +7613,7 @@ _(' abc ') ### `_.prototype[Symbol.iterator]()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7306 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7389 "View in source") [Ⓣ][1] Enables the wrapper to be iterable. @@ -7569,7 +7637,7 @@ Array.from(wrapped); ### `_.prototype.at([paths])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7158 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7236 "View in source") [Ⓣ][1] This method is the wrapper version of `_.at`. @@ -7596,7 +7664,7 @@ _(['a', 'b', 'c']).at(0, 2).value(); ### `_.prototype.chain()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7204 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7287 "View in source") [Ⓣ][1] Enables explicit method chaining on the wrapper object. @@ -7629,7 +7697,7 @@ _(users) ### `_.prototype.commit()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7233 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7316 "View in source") [Ⓣ][1] Executes the chained sequence and returns the wrapped result. @@ -7661,7 +7729,7 @@ console.log(array); ### `_.prototype.flatMap([iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7254 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7337 "View in source") [Ⓣ][1] This method is the wrapper version of `_.flatMap`. @@ -7687,7 +7755,7 @@ _([1, 2]).flatMap(duplicate).value(); ### `_.prototype.next()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7279 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7362 "View in source") [Ⓣ][1] Gets the next value on a wrapped object following the [iterator protocol](https://mdn.io/iteration_protocols#iterator). @@ -7715,7 +7783,7 @@ wrapped.next(); ### `_.prototype.plant(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7333 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7416 "View in source") [Ⓣ][1] Creates a clone of the chained sequence planting `value` as the wrapped value. @@ -7747,7 +7815,7 @@ wrapped.value(); ### `_.prototype.reverse()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7372 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7455 "View in source") [Ⓣ][1] This method is the wrapper version of `_.reverse`.
@@ -7774,7 +7842,7 @@ console.log(array); ### `_.prototype.value()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L7399 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L7486 "View in source") [Ⓣ][1] Executes the chained sequence to extract the unwrapped value. @@ -7802,7 +7870,7 @@ _([1, 2, 3]).value(); ### `_.camelCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12046 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.camelcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12191 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.camelcase "See the npm package") Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). @@ -7830,7 +7898,7 @@ _.camelCase('__foo_bar__'); ### `_.capitalize([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12065 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.capitalize "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12210 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.capitalize "See the npm package") Converts the first character of `string` to upper case and the remaining to lower case. @@ -7853,7 +7921,7 @@ _.capitalize('FRED'); ### `_.deburr([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12083 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.deburr "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12228 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.deburr "See the npm package") Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). @@ -7876,7 +7944,7 @@ _.deburr('déjà vu'); ### `_.endsWith([string=''], [target], [position=string.length])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12109 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.endswith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12254 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.endswith "See the npm package") Checks if `string` ends with the given target string. @@ -7906,7 +7974,7 @@ _.endsWith('abc', 'b', 2); ### `_.escape([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12154 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escape "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12299 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escape "See the npm package") Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to their corresponding HTML entities. @@ -7951,7 +8019,7 @@ _.escape('fred, barney, & pebbles'); ### `_.escapeRegExp([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12175 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12320 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.escaperegexp "See the npm package") Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. @@ -7974,7 +8042,7 @@ _.escapeRegExp('[lodash](https://lodash.com/)'); ### `_.kebabCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12201 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.kebabcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12346 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.kebabcase "See the npm package") Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). @@ -8002,7 +8070,7 @@ _.kebabCase('__foo_bar__'); ### `_.lowerCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12224 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lowercase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12369 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lowercase "See the npm package") Converts `string`, as space separated words, to lower case. @@ -8030,7 +8098,7 @@ _.lowerCase('__FOO_BAR__'); ### `_.lowerFirst([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12244 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lowerfirst "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12389 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.lowerfirst "See the npm package") Converts the first character of `string` to lower case. @@ -8055,7 +8123,7 @@ _.lowerFirst('FRED'); ### `_.pad([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12286 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pad "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12431 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.pad "See the npm package") Pads `string` on the left and right sides if it's shorter than `length`. Padding characters are truncated if they can't be evenly divided by `length`. @@ -8086,7 +8154,7 @@ _.pad('abc', 3); ### `_.padEnd([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12323 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padend "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12468 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padend "See the npm package") Pads `string` on the right side if it's shorter than `length`. Padding characters are truncated if they exceed `length`. @@ -8117,7 +8185,7 @@ _.padEnd('abc', 3); ### `_.padStart([string=''], [length=0], [chars=' '])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12350 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padstart "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12495 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.padstart "See the npm package") Pads `string` on the left side if it's shorter than `length`. Padding characters are truncated if they exceed `length`. @@ -8147,8 +8215,8 @@ _.padStart('abc', 3); -### `_.parseInt(string, [radix])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12378 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.parseint "See the npm package") +### `_.parseInt(string, [radix=10])` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12523 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.parseint "See the npm package") Converts `string` to an integer of the specified radix. If `radix` is `undefined` or `0`, a `radix` of `10` is used unless `value` is a hexadecimal, @@ -8160,7 +8228,7 @@ of `parseInt`. #### Arguments 1. `string` *(string)*: The string to convert. -2. `[radix]` *(number)*: The radix to interpret `value` by. +2. `[radix=10]` *(number)*: The radix to interpret `value` by. #### Returns *(number)*: Returns the converted integer. @@ -8180,7 +8248,7 @@ _.map(['6', '08', '10'], _.parseInt); ### `_.repeat([string=''], [n=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12410 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.repeat "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12555 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.repeat "See the npm package") Repeats the given string `n` times. @@ -8209,7 +8277,7 @@ _.repeat('abc', 0); ### `_.replace([string=''], pattern, replacement)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12448 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.replace "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12593 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.replace "See the npm package") Replaces matches for `pattern` in `string` with `replacement`.
@@ -8236,7 +8304,7 @@ _.replace('Hi Fred', 'Fred', 'Barney'); ### `_.snakeCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12474 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.snakecase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12619 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.snakecase "See the npm package") Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). @@ -8264,7 +8332,7 @@ _.snakeCase('--foo-bar'); ### `_.split([string=''], separator, [limit])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12495 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.split "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12640 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.split "See the npm package") Splits `string` by `separator`.
@@ -8291,7 +8359,7 @@ _.split('a-b-c', '-', 2); ### `_.startCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12518 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startcase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12663 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startcase "See the npm package") Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). @@ -8319,7 +8387,7 @@ _.startCase('__foo_bar__'); ### `_.startsWith([string=''], [target], [position=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12543 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startswith "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12688 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.startswith "See the npm package") Checks if `string` starts with the given target string. @@ -8349,7 +8417,7 @@ _.startsWith('abc', 'b', 1); ### `_.template([string=''], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12645 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.template "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12790 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.template "See the npm package") Creates a compiled template function that can interpolate data properties in "interpolate" delimiters, HTML-escape interpolated data properties in @@ -8456,7 +8524,7 @@ fs.writeFileSync(path.join(cwd, 'jst.js'), '\ ### `_.toLower([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12770 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tolower "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12916 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.tolower "See the npm package") Converts `string`, as a whole, to lower case. @@ -8484,7 +8552,7 @@ _.toLower('__FOO_BAR__'); ### `_.toUpper([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12793 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toupper "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12939 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.toupper "See the npm package") Converts `string`, as a whole, to upper case. @@ -8512,7 +8580,7 @@ _.toUpper('__foo_bar__'); ### `_.trim([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12818 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trim "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12964 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trim "See the npm package") Removes leading and trailing whitespace or specified characters from `string`. @@ -8541,7 +8609,7 @@ _.map([' foo ', ' bar '], _.trim); ### `_.trimEnd([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12854 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimend "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13002 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimend "See the npm package") Removes trailing whitespace or specified characters from `string`. @@ -8567,7 +8635,7 @@ _.trimEnd('-_-abc-_-', '_-'); ### `_.trimStart([string=''], [chars=whitespace])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12888 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimstart "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13038 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.trimstart "See the npm package") Removes leading whitespace or specified characters from `string`. @@ -8592,8 +8660,8 @@ _.trimStart('-_-abc-_-', '_-'); -### `_.truncate([string=''], [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12940 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.truncate "See the npm package") +### `_.truncate([string=''], [options=({})], [options.length=30], [options.omission='...'], [options.separator])` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13092 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.truncate "See the npm package") Truncates `string` if it's longer than the given maximum string length. The last characters of the truncated string are replaced with the omission @@ -8601,7 +8669,7 @@ string which defaults to "...". #### Arguments 1. `[string='']` *(string)*: The string to truncate. -2. `[options]` *(Object)*: The options object. +2. `[options=({})]` *(Object)*: The options object. 3. `[options.length=30]` *(number)*: The maximum string length. 4. `[options.omission='...']` *(string)*: The string to indicate text is omitted. 5. `[options.separator]` *(RegExp|string)*: The separator pattern to truncate to. @@ -8638,7 +8706,7 @@ _.truncate('hi-diddly-ho there, neighborino', { ### `_.unescape([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13014 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unescape "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13166 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.unescape "See the npm package") The inverse of `_.escape`; this method converts the HTML entities `&`, `<`, `>`, `"`, `'`, and ``` in `string` to their @@ -8666,7 +8734,7 @@ _.unescape('fred, barney, & pebbles'); ### `_.upperCase([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13040 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uppercase "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13192 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uppercase "See the npm package") Converts `string`, as space separated words, to upper case. @@ -8694,7 +8762,7 @@ _.upperCase('__foo_bar__'); ### `_.upperFirst([string=''])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L12262 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.upperfirst "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L12407 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.upperfirst "See the npm package") Converts the first character of `string` to upper case. @@ -8719,7 +8787,7 @@ _.upperFirst('FRED'); ### `_.words([string=''], [pattern])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13062 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.words "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13214 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.words "See the npm package") Splits `string` into an array of its words. @@ -8751,7 +8819,7 @@ _.words('fred, barney, & pebbles', /[^, ]+/g); ### `_.attempt(func)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13094 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.attempt "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13246 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.attempt "See the npm package") Attempts to invoke `func`, returning either the result or the caught error object. Any additional arguments are provided to `func` when it's invoked. @@ -8780,7 +8848,7 @@ if (_.isError(elements)) { ### `_.bindAll(object, methodNames)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13128 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindall "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13280 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.bindall "See the npm package") Binds methods of an object to the object itself, overwriting the existing method. @@ -8815,7 +8883,7 @@ jQuery(element).on('click', view.onClick); ### `_.cond(pairs)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13163 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.cond "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13315 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.cond "See the npm package") Creates a function that iterates over `pairs` invoking the corresponding function of the first predicate to return truthy. The predicate-function @@ -8852,7 +8920,7 @@ func({ 'a': '1', 'b': '2' }); ### `_.conforms(source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13205 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.conforms "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13357 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.conforms "See the npm package") Creates a function that invokes the predicate properties of `source` with the corresponding property values of a given object, returning `true` if @@ -8881,7 +8949,7 @@ _.filter(users, _.conforms({ 'age': _.partial(_.gt, _, 38) })); ### `_.constant(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13225 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.constant "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13377 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.constant "See the npm package") Creates a function that returns `value`. @@ -8906,7 +8974,7 @@ getter() === object; ### `_.flow([funcs])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13251 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flow "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13403 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flow "See the npm package") Creates a function that returns the result of invoking the given functions with the `this` binding of the created function, where each successive @@ -8935,7 +9003,7 @@ addSquare(1, 2); ### `_.flowRight([funcs])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13272 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flowright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13424 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.flowright "See the npm package") This method is like `_.flow` except that it creates a function that invokes the given functions from right to left. @@ -8963,7 +9031,7 @@ addSquare(1, 2); ### `_.identity(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13289 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.identity "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13441 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.identity "See the npm package") This method returns the first argument given to it. @@ -8987,12 +9055,13 @@ _.identity(object) === object; ### `_.iteratee([func=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13322 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iteratee "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13475 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.iteratee "See the npm package") Creates a function that invokes `func` with the arguments of the created function. If `func` is a property name the created callback returns the property value for a given element. If `func` is an object the created -callback returns `true` for elements that contain the equivalent object properties, otherwise it returns `false`. +callback returns `true` for elements that contain the equivalent object +properties, otherwise it returns `false`. #### Arguments 1. `[func=_.identity]` *(*)*: The value to convert to a callback. @@ -9025,11 +9094,12 @@ _.filter(users, 'age > 36'); ### `_.matches(source)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13348 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matches "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13502 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matches "See the npm package") -Creates a function that performs a deep partial comparison between a given +Creates a function that performs a partial deep comparison between a given object and `source`, returning `true` if the given object has equivalent -property values, else `false`. +property values, else `false`. The created function is equivalent to +`_.isMatch` with a `source` partially applied.

**Note:** This method supports comparing the same values as `_.isEqual`. @@ -9057,9 +9127,9 @@ _.filter(users, _.matches({ 'age': 40, 'active': false })); ### `_.matchesProperty(path, srcValue)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13375 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13529 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.matchesproperty "See the npm package") -Creates a function that performs a deep partial comparison between the +Creates a function that performs a partial deep comparison between the value at `path` of a given object to `srcValue`, returning `true` if the object value is equivalent, else `false`.
@@ -9090,7 +9160,7 @@ _.find(users, _.matchesProperty('user', 'fred')); ### `_.method(path, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13402 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.method "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13556 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.method "See the npm package") Creates a function that invokes the method at `path` of a given object. Any additional arguments are provided to the invoked method. @@ -9122,7 +9192,7 @@ _.invokeMap(_.sortBy(objects, _.method(['a', 'b', 'c'])), 'a.b.c'); ### `_.methodOf(object, [args])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13430 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.methodof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13584 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.methodof "See the npm package") The opposite of `_.method`; this method creates a function that invokes the method at a given path of `object`. Any additional arguments are @@ -9153,7 +9223,7 @@ _.map([['a', '2'], ['c', '0']], _.methodOf(object)); ### `_.mixin([object=lodash], source, [options])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13472 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mixin "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13626 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.mixin "See the npm package") Adds all own enumerable function properties of a source object to the destination object. If `object` is a function then methods are added to @@ -9198,7 +9268,7 @@ _('fred').vowels(); ### `_.noConflict()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13520 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noconflict "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13674 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noconflict "See the npm package") Reverts the `_` variable to its previous value and returns a reference to the `lodash` function. @@ -9217,7 +9287,7 @@ var lodash = _.noConflict(); ### `_.noop()` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13541 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noop "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13695 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.noop "See the npm package") A no-operation function that returns `undefined` regardless of the arguments it receives. @@ -9236,7 +9306,7 @@ _.noop(object) === undefined; ### `_.nthArg([n=0])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13560 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ntharg "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13714 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.ntharg "See the npm package") Creates a function that returns its nth argument. @@ -9260,7 +9330,7 @@ func('a', 'b', 'c'); ### `_.over(iteratees)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13583 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.over "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13737 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.over "See the npm package") Creates a function that invokes `iteratees` with the arguments provided to the created function and returns their results. @@ -9285,7 +9355,7 @@ func(1, 2, 3, 4); ### `_.overEvery(predicates)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13607 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.overevery "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13761 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.overevery "See the npm package") Creates a function that checks if **all** of the `predicates` return truthy when invoked with the arguments provided to the created function. @@ -9316,7 +9386,7 @@ func(NaN); ### `_.overSome(predicates)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13631 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.oversome "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13785 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.oversome "See the npm package") Creates a function that checks if **any** of the `predicates` return truthy when invoked with the arguments provided to the created function. @@ -9347,7 +9417,7 @@ func(NaN); ### `_.property(path)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13654 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.property "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13808 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.property "See the npm package") Creates a function that returns the value at `path` of a given object. @@ -9377,7 +9447,7 @@ _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c'); ### `_.propertyOf(object)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13678 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.propertyof "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13832 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.propertyof "See the npm package") The opposite of `_.property`; this method creates a function that returns the value at a given path of `object`. @@ -9406,7 +9476,7 @@ _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); ### `_.range([start=0], end, [step=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13723 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.range "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13877 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.range "See the npm package") Creates an array of numbers (positive and/or negative) progressing from `start` up to, but not including, `end`. A step of `-1` is used if a negative @@ -9455,7 +9525,7 @@ _.range(0); ### `_.rangeRight([start=0], end, [step=1])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13759 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rangeright "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13913 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.rangeright "See the npm package") This method is like `_.range` except that it populates values in descending order. @@ -9498,7 +9568,7 @@ _.rangeRight(0); ### `_.runInContext([context=root])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1267 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.runincontext "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1275 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.runincontext "See the npm package") Create a new pristine `lodash` function using the `context` object. @@ -9542,7 +9612,7 @@ var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; ### `_.times(n, [iteratee=_.identity])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13779 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.times "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13933 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.times "See the npm package") Invokes the iteratee function `n` times, returning an array of the results of each invocation. The iteratee is invoked with one argument; (index). @@ -9569,7 +9639,7 @@ _.times(3, String); ### `_.toPath(value)` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13822 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.topath "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13976 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.topath "See the npm package") Converts `value` to a property path array. @@ -9602,13 +9672,13 @@ console.log(path === newPath); -### `_.uniqueId([prefix])` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L13842 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqueid "See the npm package") +### `_.uniqueId([prefix=''])` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L13996 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.uniqueid "See the npm package") Generates a unique ID. If `prefix` is given the ID is appended to it. #### Arguments -1. `[prefix]` *(string)*: The value to prefix the ID with. +1. `[prefix='']` *(string)*: The value to prefix the ID with. #### Returns *(string)*: Returns the unique ID. @@ -9634,9 +9704,9 @@ _.uniqueId(); ### `_.VERSION` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L14487 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L14643 "View in source") [Ⓣ][1] -(string): The semantic version number. +({string}): The semantic version number. * * * @@ -9645,9 +9715,9 @@ _.uniqueId(); ### `_.templateSettings` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1514 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.templatesettings "See the npm package") +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1523 "View in source") [Ⓣ][1] [Ⓝ](https://www.npmjs.com/package/lodash.templatesettings "See the npm package") -(Object): By default, the template delimiters used by lodash are like those in +({Object}): By default, the template delimiters used by lodash are like those in embedded Ruby (ERB). Change the following template settings to use alternative delimiters. @@ -9658,9 +9728,9 @@ alternative delimiters. ### `_.templateSettings.escape` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1522 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1531 "View in source") [Ⓣ][1] -(RegExp): Used to detect `data` property values to be HTML-escaped. +({RegExp}): Used to detect `data` property values to be HTML-escaped. * * * @@ -9669,9 +9739,9 @@ alternative delimiters. ### `_.templateSettings.evaluate` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1530 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1539 "View in source") [Ⓣ][1] -(RegExp): Used to detect code to be evaluated. +({RegExp}): Used to detect code to be evaluated. * * * @@ -9680,9 +9750,9 @@ alternative delimiters. ### `_.templateSettings.imports` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1554 "View in source") [Ⓣ][1] +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1563 "View in source") [Ⓣ][1] -(Object): Used to import variables into the compiled template. +({Object}): Used to import variables into the compiled template. * * * @@ -9690,10 +9760,10 @@ alternative delimiters. -### `_.templateSettings.interpolate` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1538 "View in source") [Ⓣ][1] +### `_.templateSettings.imports._` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1571 "View in source") [Ⓣ][1] -(RegExp): Used to detect `data` property values to inject. +({Function}): A reference to the `lodash` function. * * * @@ -9701,27 +9771,21 @@ alternative delimiters. -### `_.templateSettings.variable` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1546 "View in source") [Ⓣ][1] +### `_.templateSettings.interpolate` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1547 "View in source") [Ⓣ][1] -(string): Used to reference the data object in the template text. +({RegExp}): Used to detect `data` property values to inject. * * * - - - - -## `Methods` - -### `_.templateSettings.imports._` -# [Ⓢ](https://github.com/lodash/lodash/blob/4.3.0/lodash.js#L1562 "View in source") [Ⓣ][1] +### `_.templateSettings.variable` +# [Ⓢ](https://github.com/lodash/lodash/blob/4.4.0/lodash.js#L1555 "View in source") [Ⓣ][1] -A reference to the `lodash` function. +({string}): Used to reference the data object in the template text. * * * diff --git a/lodash.js b/lodash.js index 4aa0a00d48..fe0fd883c6 100644 --- a/lodash.js +++ b/lodash.js @@ -1,6 +1,6 @@ /** * @license - * lodash 4.3.0 + * lodash 4.4.0 * Copyright 2012-2016 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors @@ -12,7 +12,7 @@ var undefined; /** Used as the semantic version number. */ - var VERSION = '4.3.0'; + var VERSION = '4.4.0'; /** Used to compose bitmasks for wrapper metadata. */ var BIND_FLAG = 1, diff --git a/package.json b/package.json index 5e6546e940..de3669472f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "4.3.1-pre", + "version": "4.4.0", "main": "lodash.js", "private": true, "devDependencies": { From e878559fb910f0e5e45d06c8a4d76021a4c9a5de Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 15 Feb 2016 20:13:00 -0800 Subject: [PATCH 79/79] Bump to v4.4.0. --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e2c5eb2b81..6e9e93b101 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# lodash v4.3.0 +# lodash v4.4.0 The [lodash](https://lodash.com/) library exported as a [UMD](https://github.com/umdjs/umd) module. @@ -26,14 +26,15 @@ numbers, objects, strings, etc. Lodash’s modular methods are great for: * [API Documentation](https://lodash.com/docs) * [DevDocs – *a searchable interface for our documentation*](https://devdocs.io/lodash/) + * [FP Guide](https://github.com/lodash/lodash/wiki/FP-Guide) ## Download -Lodash is released under the [MIT license](https://raw.githubusercontent.com/lodash/lodash/4.3.0/LICENSE) & supports [modern environments](#support).
+Lodash is released under the [MIT license](https://raw.githubusercontent.com/lodash/lodash/4.4.0/LICENSE) & supports [modern environments](#support).
Review the [build differences](https://github.com/lodash/lodash/wiki/build-differences) & pick the one that’s right for you. - * [Core build](https://raw.githubusercontent.com/lodash/lodash/4.3.0/dist/lodash.core.js) ([~4 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.3.0/dist/lodash.core.min.js)) - * [Full build](https://raw.githubusercontent.com/lodash/lodash/4.3.0/dist/lodash.js) ([~20 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.3.0/dist/lodash.min.js)) + * [Core build](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.core.js) ([~4 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.core.min.js)) + * [Full build](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.js) ([~20 kB gzipped](https://raw.githubusercontent.com/lodash/lodash/4.4.0/dist/lodash.min.js)) ## Module Formats @@ -42,7 +43,7 @@ Lodash is available in a variety of other builds & module formats. * [lodash](https://www.npmjs.com/package/lodash) & [per method packages](https://www.npmjs.com/browse/keyword/lodash-modularized) * [lodash-amd](https://www.npmjs.com/package/lodash-amd) * [lodash-es](https://www.npmjs.com/package/lodash-es) & [babel-plugin-lodash](https://www.npmjs.com/package/babel-plugin-lodash) - * [lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide) + * [lodash/fp](https://github.com/lodash/lodash/tree/4.4.0-npm/fp) CDN copies are available on [cdnjs](https://cdnjs.com/) & [jsDelivr](http://www.jsdelivr.com/).
Create [custom builds](https://lodash.com/custom-builds) with only the features you need.